using System.Collections;
using HAVNet.Intros.AST;




using System;

namespace HAVNet.Intros.Parsing {



public class Parser {
	public const int _EOF = 0;
	public const int _ident = 1;
	public const int _intCon = 2;
	public const int _realCon = 3;
	public const int _charCon = 4;
	public const int _stringCon = 5;
	public const int _abstract = 6;
	public const int _as = 7;
	public const int _base = 8;
	public const int _bool = 9;
	public const int _break = 10;
	public const int _byte = 11;
	public const int _case = 12;
	public const int _catch = 13;
	public const int _char = 14;
	public const int _checked = 15;
	public const int _class = 16;
	public const int _const = 17;
	public const int _continue = 18;
	public const int _decimal = 19;
	public const int _default = 20;
	public const int _delegate = 21;
	public const int _do = 22;
	public const int _double = 23;
	public const int _else = 24;
	public const int _enum = 25;
	public const int _event = 26;
	public const int _explicit = 27;
	public const int _extern = 28;
	public const int _false = 29;
	public const int _finally = 30;
	public const int _fixed = 31;
	public const int _float = 32;
	public const int _for = 33;
	public const int _foreach = 34;
	public const int _goto = 35;
	public const int _if = 36;
	public const int _implicit = 37;
	public const int _in = 38;
	public const int _int = 39;
	public const int _interface = 40;
	public const int _internal = 41;
	public const int _is = 42;
	public const int _lock = 43;
	public const int _long = 44;
	public const int _namespace = 45;
	public const int _new = 46;
	public const int _null = 47;
	public const int _object = 48;
	public const int _operator = 49;
	public const int _outKW = 50;
	public const int _override = 51;
	public const int _params = 52;
	public const int _private = 53;
	public const int _protected = 54;
	public const int _public = 55;
	public const int _readonly = 56;
	public const int _ref = 57;
	public const int _return = 58;
	public const int _sbyte = 59;
	public const int _sealed = 60;
	public const int _short = 61;
	public const int _sizeof = 62;
	public const int _stackalloc = 63;
	public const int _static = 64;
	public const int _string = 65;
	public const int _struct = 66;
	public const int _switch = 67;
	public const int _this = 68;
	public const int _throw = 69;
	public const int _true = 70;
	public const int _try = 71;
	public const int _typeof = 72;
	public const int _uint = 73;
	public const int _ulong = 74;
	public const int _unchecked = 75;
	public const int _unsafe = 76;
	public const int _ushort = 77;
	public const int _usingKW = 78;
	public const int _virtual = 79;
	public const int _void = 80;
	public const int _volatile = 81;
	public const int _while = 82;
	public const int _and = 83;
	public const int _andassgn = 84;
	public const int _arrow = 85;
	public const int _assgn = 86;
	public const int _colon = 87;
	public const int _comma = 88;
	public const int _dec = 89;
	public const int _divassgn = 90;
	public const int _dot = 91;
	public const int _dblcolon = 92;
	public const int _eq = 93;
	public const int _gt = 94;
	public const int _gteq = 95;
	public const int _inc = 96;
	public const int _lbrace = 97;
	public const int _lbrack = 98;
	public const int _lpar = 99;
	public const int _lshassgn = 100;
	public const int _lt = 101;
	public const int _ltlt = 102;
	public const int _minus = 103;
	public const int _minusassgn = 104;
	public const int _modassgn = 105;
	public const int _neq = 106;
	public const int _not = 107;
	public const int _nullCoal = 108;
	public const int _orassgn = 109;
	public const int _plus = 110;
	public const int _plusassgn = 111;
	public const int _question = 112;
	public const int _rbrace = 113;
	public const int _rbrack = 114;
	public const int _rpar = 115;
	public const int _scolon = 116;
	public const int _tilde = 117;
	public const int _times = 118;
	public const int _timesassgn = 119;
	public const int _xorassgn = 120;
	public const int _andand = 121;
	public const int _lteq = 122;
	public const int _from = 123;
	public const int _where = 124;
	public const int _join = 125;
	public const int _on = 126;
	public const int _equals = 127;
	public const int _into = 128;
	public const int _let = 129;
	public const int _orderby = 130;
	public const int _ascending = 131;
	public const int _descending = 132;
	public const int _select = 133;
	public const int _group = 134;
	public const int _by = 135;
	public const int maxT = 142;
	public const int _ppDefine = 143;
	public const int _ppUndef = 144;
	public const int _ppIf = 145;
	public const int _ppElif = 146;
	public const int _ppElse = 147;
	public const int _ppEndif = 148;
	public const int _ppLine = 149;
	public const int _ppError = 150;
	public const int _ppWarning = 151;
	public const int _ppRegion = 152;
	public const int _ppEndReg = 153;
	public const int _ppPragma = 154;

	const bool T = true;
	const bool x = false;
	const int minErrDist = 2;
	
	public Scanner scanner;
	public Errors  errors;

	/*****************************************/
	/******* agregado por ale ****************/
	TerminalSymbolFunction			tsym	= null;
	NonTerminalSymbolFunction		ntsym	= null;
	LeaveNonTerminalSymbolFunction	lntsym	= null;
	int depth = 0;
	/*****************************************/
	
	public Token t;    // last recognized token
	public Token la;   // lookahead token
	int errDist = minErrDist;

public ASTCS3 ast = new ASTCS3 ("Prueba");


/*---------------------- conditional compilation symbols -----------------*/

ArrayList ccs = new ArrayList();

public void AddConditionalCompilationSymbols(string[] symbols) {
  if (symbols != null) {
    for (int i=0; i<symbols.Length; ++i) {
      symbols[i] = symbols[i].Trim();
      if (symbols[i].Length > 0 && !ccs.Contains(symbols[i])) {
        ccs.Add(symbols[i]);
      }
    }
  }
}

// returns the end of the whitespaces in the given
// string if whitespaces is true otherwise returns
// the end of the non-whitespaces.
int EndOf(string symbol, int start, bool whitespaces) {
  while ((start < symbol.Length) && (Char.IsWhiteSpace(symbol[start]) ^ !whitespaces)) {
    ++start;
  }

  return start;
}

// input:        "#" {ws} directive ws {ws} {not-newline} {newline}
// valid input:  "#" {ws} directive ws {ws} {non-ws} {ws} {newline}
// output:       {non-ws}
string RemPPDirective(string symbol) {
  int start = 1;
  int end;

  // skip {ws}
  start = EndOf(symbol, start, true);
  // skip directive
  start = EndOf(symbol, start, false);
  // skip ws {ws}
  start = EndOf(symbol, start, true);
  // search end of symbol
  end = EndOf(symbol, start, false);
  
  return symbol.Substring(start, end - start);
}

void AddCCS(string symbol) {
  symbol = RemPPDirective(symbol);
  if (!ccs.Contains(symbol)) {
    ccs.Add(symbol);
  }
}

void RemCCS(string symbol) {
  ccs.Remove(RemPPDirective(symbol));
}


// preprocessor expression parser start
bool PPOrExpression(PPScanner scan) {
  bool e1, e2;
  
  e1 = PPAndExpression(scan);
  while (scan.peek().getKind() == PPToken.eOr) {
    scan.next();
    e2 = PPAndExpression(scan);
    e1 = e1 || e2;
  }
  
  return e1;
}

bool PPAndExpression(PPScanner scan) {
  bool e1, e2;
  e1 = PPEqualityExpression(scan);
  
  while (scan.peek().getKind() == PPToken.eAnd) {
    scan.next();
    e2 = PPEqualityExpression(scan);
    e1 = e1 && e2;
  }
  
  return e1;
}

bool PPEqualityExpression(PPScanner scan) {
  bool e1, e2;
  
  e1 = PPUnaryExpression(scan);
  int tk = scan.peek().getKind();
  
  while (tk == PPToken.eEQ || tk == PPToken.eNE) {
    scan.next();
    e2 = PPUnaryExpression(scan);
    if (tk == PPToken.eEQ) {
      e1 = e1 == e2;
    } else {
      // tk == PPToken.eNE
      e1 = e1 != e2;
    }
    tk = scan.peek().getKind();
  }
  
  return e1;
}

bool PPUnaryExpression(PPScanner scan) {
  bool not = false;
  PPToken ppt = scan.peek();
  
  while (ppt.getKind() == PPToken.eNot) {
    scan.next();
    not = !not;
    ppt = scan.peek();
  }
  
  return not ^ PPPrimaryExpression(scan);
}

bool PPPrimaryExpression(PPScanner scan) {
  bool e = false;
  PPToken ppt = scan.next();
  
  if (ppt.getKind() == PPToken.eTrue) {
    e = true;
  } else if (ppt.getKind() == PPToken.eFalse) {
    e = false;
  } else if (ppt.getKind() == PPToken.eLPar) {
    e = PPOrExpression(scan);
    ppt = scan.next();
    if (ppt.getKind() != PPToken.eRPar) {
      Error("Corrupt preprocessor directive (')' expected), found: " + ppt.toString());
    }
  } else if (ppt.getKind() == PPToken.eIdent) {
    e = ccs.Contains(ppt.getValue());
  } else {
    Error("Corrupt preprocessor directive, unknown start of PPPrimaryExpression: " + ppt.toString());
  }
  
  return e;
}
// preprocessor expression parser end

// ccs.Contains(RemPPDirective(symbol))
bool IsCCS(string symbol) {
  // skip "#" "if", "#" "elif"
  PPScanner scan = new PPScanner(symbol);
  PPToken ppt = scan.next();
  if (ppt.getKind() != PPToken.eHash) {
      Error("Corrupt preprocessor directive, # expected, but found: " + ppt.toString());
  }
  ppt = scan.next();
  if (ppt.getKind() != PPToken.eIdent) {
      Error("Corrupt preprocessor directive, identifier expected, but found: " + ppt.toString());
  }
  return PPOrExpression(scan);
}

// search for the correct alternative and enter
// drop everything before the correct alternative
void IfPragma(string symbol) {
  if (!IsCCS(symbol)) { 
    int state = 0;
    Token cur = ScanOrPeek();
    
    for (;;) {
      switch (cur.kind) {
        case _ppIf: ++state; break;
        case _ppEndif:
          if (state == 0) { return; }
          --state;
        break;
        case _ppElif:
          if (state == 0 && IsCCS(cur.val)) { return; }
        break;
        case _ppElse:
          if (state == 0) { return; }
        break;
        case _EOF: Error("Incomplete file."); return;
        default: break;
      }
      cur = ScanOrPeek();
    }
  }
}

// drop everything until the end of this if, elif, else directive
void ElifOrElsePragma() {
  int state = 0;
  Token cur = ScanOrPeek();
  
  for (;;) {
    switch (cur.kind) {
      case _ppIf: ++state; break;
      case _ppEndif:
        if (state == 0) { return; }
        --state;
      break;
      case _EOF: Error("Incomplete file."); return;
      default: break;
    }
    cur = ScanOrPeek();
  }
}

public class PPScanner {
	private const int cEOF = -1;
	private char[] fChars;
	private int fPos;
	private PPToken fNext;
	private int fChar;
	// all start characters of symbol tokens (non ident tokens).
	private readonly char[] fSymbolTokenStart = { '#', '!', '=', '&', '|', '(', ')' }; 

	public PPScanner(string str) {
		fChars = str.ToCharArray();
		fPos = 0;
		fNext = null;
		nextCh();
	}

	private void nextCh() {
		if (fPos < fChars.Length) {
			fChar = fChars[fPos];
			++fPos;
		} else {
			fChar = -1;
		}
	}

	private string readIdent() {
		System.Text.StringBuilder sb = new System.Text.StringBuilder();
		do {
			sb.Append((char) fChar);
			nextCh();
		} while (fChar != cEOF && !Char.IsWhiteSpace((char) fChar) && !isSymbolTokenStart((char) fChar));
		return sb.ToString();
	}

	private bool isSymbolTokenStart(char c) {
		for (int i = 0; i < fSymbolTokenStart.Length; ++i) {
			if (fSymbolTokenStart[i] == c) {
				return true;
			}
		}
		return false;
	}

	private PPToken scan() {
		PPToken t = new PPToken();
		while (fChar != cEOF && Char.IsWhiteSpace((char) fChar)) {
			// Skip whitespaces
			nextCh();
		}
		switch (fChar) {
		case '#':
			t.setKind(PPToken.eHash);
			nextCh();
			break;
		case '!':
			t.setKind(PPToken.eNot);
			nextCh();
			if (fChar == '=') {
				t.setKind(PPToken.eNE);
				nextCh();
			}
			break;
		case '=':
			t.setKind(PPToken.eAssign);
			nextCh();
			if (fChar == '=') {
				t.setKind(PPToken.eEQ);
				nextCh();
			}
			break;
		case '&':
			nextCh();
			if (fChar == '&') {
				nextCh();
				t.setKind(PPToken.eAnd);
			} else {
				t.setKind(PPToken.eError);
			}
			break;
		case '|':
			nextCh();
			if (fChar == '|') {
				nextCh();
				t.setKind(PPToken.eOr);
			} else {
				t.setKind(PPToken.eError);
			}
			break;
		case '(':
			t.setKind(PPToken.eLPar);
			nextCh();
			break;
		case ')':
			t.setKind(PPToken.eRPar);
			nextCh();
			break;
		case cEOF:
			t.setKind(PPToken.eEOF);
			break;
		default:
			String val = readIdent();
			if (val.Equals("true")) {
				t.setKind(PPToken.eTrue);
			} else if (val.Equals("false")) {
				t.setKind(PPToken.eFalse);
			} else {
				t.setKind(PPToken.eIdent);
				t.setValue(val);
			}
			break;
		}
		return t;
	}

	public PPToken peek() {
		if (fNext == null) {
			fNext = scan();
		}
		return fNext;
	}

	public PPToken next() {
		PPToken t;
		if (fNext != null) {
			t = fNext;
			fNext = null;
		} else {
			t = scan();
		}
		return t;
	}
}

public class PPToken {
	public const int eEOF    = 0;
	public const int eHash   = 1;
	public const int eNot    = 2;
	public const int eAssign = 3;
	public const int eAnd    = 4;
	public const int eOr     = 5;
	public const int eLPar   = 6;
	public const int eRPar   = 7;
	public const int eTrue   = 8;
	public const int eFalse  = 9;
	public const int eIdent  = 10;
	public const int eEQ     = 11;
	public const int eNE     = 12;
	public const int eError  = 13;

	private readonly string[] sfTokenNames = {"EOF", "#", "!", "=", "&&", "||", "(",
			")", "true", "false", "Identifier", "==", "!=", "Error"};
	private const string cUnknownToken = "Unknown Token";
	
	private int fKind;
	public string fVal;
	
	public void setKind(int kind) {
		fKind = kind;
	}
	
	public int getKind() {
		return fKind;
	}
	
	public void setValue(string value) {
		fVal = value;
	}
	
	public string getValue() {
		return fVal;
	}
	
	public string toString() {
		string s;
		if (fKind >= 0 && fKind < sfTokenNames.Length) {
			s = sfTokenNames[fKind];
			if (fKind == eIdent) {
				s = s + ": " + fVal;
			}
		} else {
			s = cUnknownToken;
		}
		return s;
	}
}

/*----------------------------- token sets -------------------------------*/

const int maxTerminals = 160;  // set size

static BitArray NewSet(int[] values) {
  BitArray a = new BitArray(maxTerminals);
  foreach (int x in values) a[x] = true;
  return a;
}

static BitArray
  typeDeclStart= NewSet(new int[] {_class, _struct, _interface, _enum, _delegate}),
  typeKW       = NewSet(new int[] {_char, _bool, _object, _string, _sbyte, _byte, _short,
                 _ushort, _int, _uint, _long, _ulong, _float, _double, _decimal}),
  unaryHead    = NewSet(new int[] {_plus, _minus, _not, _tilde, _times, _inc, _dec, _and}),
  assnStartOp  = NewSet(new int[] {_plus, _minus, _not, _tilde, _times}),
  castFollower = NewSet(new int[] {_tilde, _not, _lpar, _ident,
                 /* literals */
                 _intCon, _realCon, _charCon, _stringCon,
                 /* any keyword expect as and is */
                 _abstract, _base, _bool, _break, _byte, _case, _catch,
                 _char, _checked, _class, _const, _continue, _decimal, _default,
                 _delegate, _do, _double, _else, _enum, _event, _explicit,
                 _extern, _false, _finally, _fixed, _float, _for, _foreach,
                 _goto, _if, _implicit, _in, _int, _interface, _internal,
                 _lock, _long, _namespace, _new, _null, _object, _operator,
                 _outKW, _override, _params, _private, _protected, _public,
                 _readonly, _ref, _return, _sbyte, _sealed, _short, _sizeof,
                 _stackalloc, _static, _string, _struct, _switch, _this, _throw,
                 _true, _try, _typeof, _uint, _ulong, _unchecked, _unsafe,
                 _ushort, _usingKW, _virtual, _void, _volatile, _while
                 }),
  typArgLstFol = NewSet(new int[] {_lpar, _rpar, _rbrack, _colon, _scolon, _comma, _dot,
                 _question, _eq, _neq, _gt, _nullCoal, _lt, _lteq, _gteq, _is, _as, _andand}),
  keyword      = NewSet(new int[] {_abstract, _as, _base, _bool, _break, _byte, _case, _catch,
                 _char, _checked, _class, _const, _continue, _decimal, _default,
                 _delegate, _do, _double, _else, _enum, _event, _explicit,
                 _extern, _false, _finally, _fixed, _float, _for, _foreach,
                 _goto, _if, _implicit, _in, _int, _interface, _internal,
                 _is, _lock, _long, _namespace, _new, _null, _object, _operator,
                 _outKW, _override, _params, _private, _protected, _public,
                 _readonly, _ref, _return, _sbyte, _sealed, _short, _sizeof,
                 _stackalloc, _static, _string, _struct, _switch, _this, _throw,
                 _true, _try, _typeof, _uint, _ulong, _unchecked, _unsafe,
                 _ushort, _usingKW, _virtual, _void, _volatile, _while}),
  assgnOps     = NewSet(new int[] {_assgn, _plusassgn, _minusassgn, _timesassgn, _divassgn,
                 _modassgn, _andassgn, _orassgn, _xorassgn, _lshassgn}) /* rshassgn: ">" ">="  no whitespace allowed*/,
                 
  firstExpr    /*
                 The first set of expressions are used to determine if a "?" symbol
                 counts as a nullable qualifier or belogns to the conditional operator.
                 This is a wild guess because there is no solution for this problem in the spec.
               */
               = NewSet(new int[] { _ident, _intCon, _realCon, _charCon, _stringCon, _base,
                 _bool, _byte, _char, _checked, _decimal, _default, _delegate, _double, _false,
                 _float, _int, _long, _new, _null, _object, _sbyte, _short, _sizeof, _string, _this,
                 _true, _typeof, _uint, _ulong, _unchecked, _ushort, _and, _dec, _inc, _lpar, _minus,
                 _not, _plus, _tilde, _times })
                 ;

/*---------------------------- auxiliary methods ------------------------*/

void Error (string s) {
  if (errDist >= minErrDist) errors.SemErr(la.line, la.col, s);
  errDist = 0;
}

// Return the n-th token after the current lookahead token
Token Peek (int n) {
  scanner.ResetPeek();
  Token _x = la;
  while (n > 0) {
    _x = PeekWithPragmas();
    n--;
  }
  return _x;
}

Token Copy(Token t) {
    Token copy = new Token();
    copy.kind = t.kind;
    copy.pos = t.pos;
    copy.col = t.col;
    copy.line = t.line;
    copy.val = t.val;
    return copy;
}

Token CopyTokens(Token start, Token end) {
    Token tokens = Copy(start);

    Token t = tokens;
    while(true) {
       start = start.next;
       if (start == end) break;
       if (start.kind > maxT) continue;
       t = t.next = Copy(start);
    }
	return tokens;
}

// A pragmas sensitive Peek mehtod.
Token PeekWithPragmas() {
  Token _x = scanner.PeekWithPragmas();
  while (_x.kind > maxT) {
    // Handle Pragma, this MUST stay in SYNC with the semantic actions of the pragmas!
    isScanMode = false;
    if (_x.kind == _ppDefine) {
      AddCCS(_x.val); 
    }
    else if (_x.kind == _ppUndef) {
      RemCCS(_x.val); 
    }
    else if (_x.kind == _ppIf) {
      IfPragma(_x.val); 
    }
    else if (_x.kind == _ppElif) {
      ElifOrElsePragma(); 
    }
    else if (_x.kind == _ppElse) {
      ElifOrElsePragma(); 
    }
    isScanMode = true;
    _x = scanner.PeekWithPragmas();
  }
  return _x;
}

/* This method will be used by the pragma handlers because we
 * have to decide if the pragma works in peek mode (in a resolver)
 * or in normal scan mode (called from get while parsing).
 */
private bool isScanMode = true;
Token ScanOrPeek () {
  if (isScanMode) {
    return scanner.Scan();
  } else {
    return scanner.PeekWithPragmas();
  }
}

// ident "="
bool IsAssignment () {
  return kindInContext(la.kind) == _ident && Peek(1).kind == _assgn;
}

/* True, if the comma is not a trailing one, *
 * like the last one in: a, b, c,            */
bool NotFinalComma () {
  int peek = Peek(1).kind;
  return la.kind == _comma && peek != _rbrace && peek != _rbrack;
}

/* Checks whether the next sequence of tokens is a qualident *
 * and returns the next token after the qualident            *
 * !!! Proceeds from current peek position !!!               */
Token IsQualident (Token pt) {
    if (kindInContext(pt.kind) == _ident) {
        pt = PeekWithPragmas();
        while (pt.kind == _dot) {
            pt = PeekWithPragmas();
            if (kindInContext(pt.kind) != _ident) return null;
            pt = PeekWithPragmas();
        }
        return pt;
    } else return null;
}

bool IsGeneric() {
  scanner.ResetPeek();
  Token pt = la;
  pt = IsTypeArgumentList(pt);
  return pt != null && typArgLstFol[kindInContext(pt.kind)];
}

/* returns the token after the type argument list *
 * if type argument list could be recognized,     *
 * otherwise null.                                */
Token IsTypeArgumentList(Token pt) {
  if (pt.kind == _lt) {
    pt = PeekWithPragmas();
    while (true) {
      pt = IsType(pt);
      if (pt == null) {
        return null;
      }
      if (pt.kind == _gt) {
        // list recognized
        pt = PeekWithPragmas();
        break;
      } else if (pt.kind == _comma) {
        // another argument
        pt = PeekWithPragmas();
      } else {
        // error in type argument list
        return null;
      }
    }
  } else {
    return null;
  }
  return pt;
}

/* Stores if the last IsType recognized a pointer or array type. *
 * This flag does not mean anything if the last call of IsType   *
 * did not recognize a type.                                     */
bool wasPointerOrArrayType;

/* returns the token after the type               *
 * if a type could be recognized, otherwise null. */
Token IsType (Token pt) {
  wasPointerOrArrayType = false;
  if (typeKW[kindInContext(pt.kind)]) {
    pt = PeekWithPragmas();
  } else if (pt.kind == _void) {
    pt = PeekWithPragmas();
    if (pt.kind != _times) {
      return null;
    }
    wasPointerOrArrayType = true;
    pt = PeekWithPragmas();
  } else if (kindInContext(pt.kind) == _ident) {
    pt = PeekWithPragmas();
    if (pt.kind == _dblcolon || pt.kind == _dot) {
      // either namespace alias qualifier "::" or first
      // part of the qualident
      pt = PeekWithPragmas();
      pt = IsQualident(pt);
      if (pt == null) {
        return null;
      }
    } 
    if (pt.kind == _lt) {
      pt = IsTypeArgumentList(pt);
      if (pt == null) {
        return null;
      }
      if (pt.kind == _dot) {
        pt = PeekWithPragmas();
        pt = IsType(pt);
        if (pt == null) {
          return null;
        }
      }
    }
  } else {
    return null;
  }
  if (pt.kind == _question) {
    pt = PeekWithPragmas();
  }
  
  Token prePt = pt;
  pt = SkipPointerOrDims(pt);
  wasPointerOrArrayType |= prePt != pt;
  
  return pt;
}

// Type ident
// (Type can be void*)
bool IsLocalVarDecl() {
  Token pt = la;
  scanner.ResetPeek();
  pt = IsType(pt);
  return pt != null && kindInContext(pt.kind) == _ident;
}

// "[" ("," | "]")
bool IsDims () {
  int peek = Peek(1).kind;
  return la.kind == _lbrack && (peek == _comma || peek == _rbrack);
}

// "*" | "[" ("," | "]")
bool IsPointerOrDims () {
  return la.kind == _times || IsDims();
}

/* skip: { "[" { "," } "]" | "*" }                   */
/* returns the next token after the pointer of dims  */
/* or null if not recognized                         */
/* !!! Proceeds from current peek position !!!       */
Token SkipPointerOrDims (Token pt) {
  for (;;) {
    if (pt.kind == _lbrack) {
      do pt = PeekWithPragmas();
      while (pt.kind == _comma);
      if (pt.kind != _rbrack) return null;
    } else if (pt.kind != _times) break;
    pt = PeekWithPragmas();
  }
  return pt;
}

// Is attribute target specifier
// (ident | keyword) ":"
bool IsAttrTargSpec () {
  return (kindInContext(la.kind) == _ident || keyword[kindInContext(la.kind)]) && Peek(1).kind == _colon;
}

// ident ("," | "=" | ";")
bool IsFieldDecl () {
  int peek = Peek(1).kind;
  return kindInContext(la.kind) == _ident && 
         (peek == _comma || peek == _assgn || peek == _scolon);
}

bool IsTypeCast () {
  if (la.kind != _lpar) return false;
  if (IsSimpleTypeCast()) return true;
  return GuessTypeCast();
}

// "(" typeKW ")"
bool IsSimpleTypeCast () {
    // assert: la.kind == _lpar
    scanner.ResetPeek();
    Token pt1 = PeekWithPragmas();
    Token pt2 = PeekWithPragmas();
    return typeKW[kindInContext(pt1.kind)] &&
            (pt2.kind == _rpar ||
            (pt2.kind == _question && PeekWithPragmas().kind == _rpar));
}

// "(" Type ")" castFollower
bool GuessTypeCast () {
  // assert: la.kind == _lpar
  Token pt = Peek(1);
  pt = IsType(pt);
  if (pt == null) {
    return false;
  }
  if (pt.kind != _rpar) {
    return false;
  }
  pt = PeekWithPragmas();
  return castFollower[kindInContext(pt.kind)] ||
        /* & for unsafe context */
        (wasPointerOrArrayType && pt.kind == _and);
}

// "[" "assembly"
bool IsGlobalAttrTarget () {
  Token pt = Peek(1);
  return la.kind == _lbrack && kindInContext(pt.kind) == _ident && (pt.val.Equals("assembly") || pt.val.Equals("module"));
}

// "extern" "alias"
// where alias is an identifier, no keyword
bool IsExternAliasDirective () {
  return la.kind == _extern && Peek(1).val.Equals("alias");
}

// true: anyToken"<"
// no whitespace between the token and the "<" allowed
// anything else will return false.
bool IsLtNoWs() {
  return (la.kind == _lt) && ((t.pos + t.val.Length) == la.pos);
}

bool IsNoSwitchLabelOrRBrace() {
  return (la.kind != _case && la.kind != _default && la.kind != _rbrace) ||
         (la.kind == _default && Peek(1).kind != _colon);
}

bool IsShift() {
  Token pt = Peek(1);
  return (la.kind == _ltlt) ||
         ( la.kind == _gt &&
           pt.kind == _gt &&
           (la.pos + la.val.Length == pt.pos)
         );
}

bool IsTypeDeclaration() {
  if (typeDeclStart[kindInContext(la.kind)]) {
    return true;
  }
  Token pt = Peek(1);
  return kindInContext(la.kind) == _ident && "partial".Equals(la.val) && typeDeclStart[kindInContext(pt.kind)];
}

// true: TypeArgumentList followed by anything but "("
bool IsPartOfMemberName() {
  scanner.ResetPeek();
  Token pt = la;
  pt = IsTypeArgumentList(pt);
  return pt != null && pt.kind != _lpar;
}

bool IsImplicitTypedLambdaExpression() {
  Token pt = Peek(1);
  if (kindInContext(la.kind) == _ident && pt.kind == _arrow) {
    // x => 
    return true;
  }
  if (la.kind != _lpar || kindInContext(pt.kind) != _ident) {
    // no start of implicit typed lambda expression
    return false;
  }
  pt = PeekWithPragmas();
  // (x  ,    y, z) =>
  while (pt.kind == _comma) {
    pt = PeekWithPragmas();
    if (kindInContext(pt.kind) != _ident) {
      // after a comma there must be an ident
      return false;
    }
    pt = PeekWithPragmas();
  }
  return pt.kind == _rpar && PeekWithPragmas().kind == _arrow;
}

bool IsExplicitTypedLambdaExpression() {
  if (la.kind != _lpar) {
    return false;
  }
  // (
  Token pt = Peek(0);
  int nPars = 1;
  // skip explicitly typed lambda parameterlist sloppy
  while (nPars > 0) {
    pt = PeekWithPragmas();
    if (pt.kind == _EOF) break;
    if (pt.kind == _lpar) { ++nPars; }
    else if (pt.kind == _rpar) { --nPars; }
  }
  // ( formal parameters )
  // check for "=>"
  return PeekWithPragmas().kind == _arrow;
}

bool IsYieldReturn() {
  if (la.kind != _ident) {
    return false;
  }
  Token pt = Peek(1);
  return pt.kind == _return || pt.kind == _break;
}

// TypeKind
enum TypeKind {simple, array, pointer, @void}

// Operator
const int
  plusOp   = 0x00000001, minusOp  = 0x00000002, notOp    = 0x00000004, tildeOp  = 0x00000008,
  incOp    = 0x00000010, decOp    = 0x00000020, trueOp   = 0x00000040, falseOp  = 0x00000080,
  timesOp  = 0x00000100, divOp    = 0x00000200, modOp    = 0x00000400, andOp    = 0x00000800,
  orOp     = 0x00001000, xorOp    = 0x00002000, lshiftOp = 0x00004000, rshiftOp = 0x00008000,
  eqOp     = 0x00010000, neqOp    = 0x00020000, gtOp     = 0x00040000, ltOp     = 0x00080000,
  gteOp    = 0x00100000, lteOp    = 0x00200000,
  unaryOp  = plusOp|minusOp|notOp|tildeOp|incOp|decOp|trueOp|falseOp,
  binaryOp = plusOp|minusOp|timesOp|divOp|modOp|andOp|orOp|xorOp|lshiftOp|rshiftOp|eqOp|neqOp|gtOp|ltOp|gteOp|lteOp;

/*------------------------- modifier handling -----------------------------*/

// Modifier
private const long
  newMod      = 0x0001, publicMod = 0x0002, protectedMod= 0x0004, internalMod = 0x0008,
  privateMod  = 0x0010, unsafeMod = 0x0020, staticMod   = 0x0040, readonlyMod = 0x0080,
  volatileMod = 0x0100, virtualMod= 0x0200, sealedMod   = 0x0400, overrideMod = 0x0800,
  abstractMod = 0x1000, externMod = 0x2000,

  /* sets of modifiers that can be attached to certain program elements    *
   * e.g., "constants" marks all modifiers that may be used with constants */
  noneMod             = 0x0000,
  classesMod          = newMod|publicMod|protectedMod|internalMod|privateMod|unsafeMod|abstractMod|sealedMod|staticMod,
  constantsMod        = newMod|publicMod|protectedMod|internalMod|privateMod,
  fieldsMod           = newMod|publicMod|protectedMod|internalMod|privateMod|unsafeMod|staticMod|readonlyMod|volatileMod,
  propEvntMethsMod    = newMod|publicMod|protectedMod|internalMod|privateMod|unsafeMod|staticMod|virtualMod|sealedMod|overrideMod|abstractMod|externMod,
  accessorsPossib1Mod = privateMod,
  accessorsPossib2Mod = protectedMod|internalMod,
  indexersMod         = newMod|publicMod|protectedMod|internalMod|privateMod|unsafeMod|virtualMod|sealedMod|overrideMod|abstractMod|externMod,
  operatorsMod        = publicMod|unsafeMod|staticMod|externMod,
  operatorsMustMod    = publicMod|staticMod,
  constructorsMod     = publicMod|protectedMod|internalMod|privateMod|unsafeMod|externMod,
  staticConstrMod     = externMod|staticMod,
  staticConstrMustMod = staticMod,
  nonClassTypesMod    = newMod|publicMod|protectedMod|internalMod|privateMod|unsafeMod,
  destructorsMod      = externMod|unsafeMod,
  allMod              = 0x3fff;

private class Modifiers {
  private long cur = noneMod;
  private Parser parser;

  public Modifiers(Parser parser) {
    this.parser = parser;
  }

  public void Add (long m) {
    if ((cur & m) == 0) cur |= m;
    else parser.Error("modifier " + m + " already defined");
  }

  public void Add (Modifiers m) { Add(m.cur); }

  public bool IsNone() { return cur == noneMod; }

  public void Check (long allowed) {
    long wrong = cur & (allowed ^ allMod);
    if (wrong != noneMod)
      parser.Error("modifier(s) " + wrong + " not allowed here");
  }

  public void Check (long allowEither, long allowOr) {
    long wrong = cur & ((allowEither|allowOr) ^ allMod);
    if ((allowEither&allowOr) != noneMod) {
      parser.Error("modifiers providerd must not overlap");
    } else if (wrong != noneMod) {
      parser.Error("modifier(s) " + wrong + " not allowed here");
    } else if (((cur&allowEither) != noneMod) && ((cur&allowOr) != noneMod)) {
      parser.Error("modifier(s) may either be " + allowEither + " or " + allowOr);
    }
  }

  public void CheckMust (long mustHave) {
    long missing = (cur&mustHave)^mustHave;
    if (missing != noneMod) {
      parser.Error("modifier(s) " + missing + " must be applied here");
    }
  }

  public bool Has (long mod) {
    return (cur&mod) == mod;
  }
  
  public long getModifiers ()
  {
	return cur;
  }
}

// LINQ Context switch

Hashtable litInOtherContext = new Hashtable();

// will be used to restore the special context kind.
int lastKind;

// contextDepth stores the recursion depth of the context, if we are in the context
// the value is > 0, outside it is 0
int contextDepth = 0;


void fillContextLitMap() {
    litInOtherContext[_from] = _ident;
    litInOtherContext[_where] = _ident;
    litInOtherContext[_join] = _ident;
    litInOtherContext[_on] = _ident;
    litInOtherContext[_equals] = _ident;
    litInOtherContext[_into] = _ident;
    litInOtherContext[_let] = _ident;
    litInOtherContext[_orderby] = _ident;
    litInOtherContext[_ascending] = _ident;
    litInOtherContext[_descending] = _ident;
    litInOtherContext[_select] = _ident;
    litInOtherContext[_group] = _ident;
    litInOtherContext[_by] = _ident;
}


int kindInContext(int kind) {
    if (contextDepth == 0) {
        // subtract extra literals from the special context as we are in normal context
        if (litInOtherContext.Contains(kind)) {
            return (int) litInOtherContext[kind];
        }
    }
    return kind;
}

void switchTokenContext() {
    // save the original kind of the token in case we have to restore it
    lastKind = la.kind;
    la.kind = kindInContext(la.kind);
}

void leaveContext() {
    // assert: contextDepth > 0;
    --contextDepth;
    if (contextDepth == 0) {
        switchTokenContext();
    }
}

void enterContext() {
    ++contextDepth;
}

void checkForContextSwitch() {
    if (contextDepth > 0) {
        // nothing to do, we are already in context.
        return;
    }
    // check for context switch
    if (lastKind ==  _from && 
        (Peek(1).kind == _ident || IsType(Peek(1)) != null) && 
        Peek(2).kind != _scolon && Peek(2).kind != _comma && 
        Peek(2).kind != _eq)    {
        // restore la token if we need a token switch
        la.kind = lastKind;
    }
}

Stack tryResults = new Stack();

/*------------------------------------------------------------------------*
 *----- SCANNER DESCRIPTION ----------------------------------------------*
 *------------------------------------------------------------------------*/



	public Parser (Scanner scanner) : this (scanner, null, null, null)
	{ }
	
	public Parser (
		Scanner							scanner,
		TerminalSymbolFunction			tsym,
		NonTerminalSymbolFunction		ntsym,
		LeaveNonTerminalSymbolFunction	lntsym
	)
	{
		this.scanner	= scanner;
		this.tsym		= tsym;
		this.ntsym		= ntsym;
		this.lntsym		= lntsym;
		errors			= new Errors();
	}

	void SynErr (int n) {
		if (errDist >= minErrDist)
			errors.SynErr(la.line, la.col, n);
		
		errDist = 0;
	}

	public void SemErr (string msg) {
		if (errDist >= minErrDist)
			errors.SemErr(t.line, t.col, msg);
		
		errDist = 0;
	}
		
	void Get () {
		for (;;) {
			t = la;
			la = scanner.Scan();
			if (la.kind <= maxT) { switchTokenContext(); ++errDist; break; }
					if (la.kind == 143) {
				AddCCS(la.val); 
				}
				if (la.kind == 144) {
				RemCCS(la.val); 
				}
				if (la.kind == 145) {
				IfPragma(la.val); 
				}
				if (la.kind == 146) {
				ElifOrElsePragma(); 
				}
				if (la.kind == 147) {
				ElifOrElsePragma(); 
				}
				if (la.kind == 148) {
				}
				if (la.kind == 149) {
				}
				if (la.kind == 150) {
				}
				if (la.kind == 151) {
				}
				if (la.kind == 152) {
				}
				if (la.kind == 153) {
				}
				if (la.kind == 154) {
				}

			la = t;
		}
	}
	
	void Expect (int n) {
		if (la.kind==n) Get(); else { SynErr(n); }
	}
	
	bool StartOf (int s) {
		return set[s, la.kind];
	}
	
	void ExpectWeak (int n, int follow) {
		if (la.kind == n) Get();
		else {
			SynErr(n);
			while (!StartOf(follow)) Get();
		}
	}

	bool WeakSeparator(int n, int syFol, int repFol) {
		int kind = la.kind;
		if (kind == n) {Get(); return true;}
		else if (StartOf(repFol)) {return false;}
		else {
			SynErr(n);
			while (!(set[syFol, kind] || set[repFol, kind] || set[0, kind])) {
				Get();
				kind = la.kind;
			}
			return StartOf(syFol);
		}
	}
	
	void CS3() {
		fillContextLitMap		();
		ASTUsing				au;
		ASTExternAliasDirective	ead;
		ASTGlobalAttributes		gattrs;
		ASTNamespaceMemberDecl	nmd;
		
		ntsym ("CS3", depth); ++depth; 
		while (IsExternAliasDirective()) {
			ExternAliasDirective(out ead);
			ast.externalAliasDirectives.Add(ead); 
		}
		while (la.kind == 78) {
			UsingDirective(out au);
			ast.usings.Add(au); 
		}
		while (IsGlobalAttrTarget()) {
			GlobalAttributes(out gattrs);
			ast.globalAttributesList.Add	(gattrs); 
		}
		while (StartOf(1)) {
			NamespaceMemberDeclaration(out nmd);
			ast.namespaceMemberDecls.Add(nmd); 
		}
		lntsym (); --depth; 
	}

	void ExternAliasDirective(out ASTExternAliasDirective ead) {
		ntsym ("ExternAliasDirective", depth); 
		++depth; 
		Expect(28);
		tsym (t, depth); 
		Expect(1);
		tsym (t, depth); 
		if (! t.val.Equals("alias")) { Error("alias expected"); } 
		Expect(1);
		tsym (t, depth); 
		ead = new ASTExternAliasDirective(t.val); 
		Expect(116);
		tsym (t, depth); 
		lntsym (); --depth; 
	}

	void UsingDirective(out ASTUsing au) {
		ASTTypeName	typeName;
		string		usingAlias = "";
		
		ntsym ("UsingDirective", depth); 
		++depth; 
		Expect(78);
		tsym (t, depth); 
		if (IsAssignment()) {
			Expect(1);
			tsym (t, depth); 
			usingAlias += t.val; 
			Expect(86);
			tsym (t, depth); 
		}
		TypeName(out typeName);
		Expect(116);
		tsym (t, depth); 
		au = new ASTUsing("" , typeName, usingAlias); 
		lntsym (); --depth; 
	}

	void GlobalAttributes(out ASTGlobalAttributes gattrs) {
		ntsym ("GlobalAttributes", depth); 
		++depth; 
		gattrs = new ASTGlobalAttributes (); ASTAttribute attribute; 
		Expect(98);
		tsym (t, depth); 
		Expect(1);
		tsym (t, depth); 
		gattrs.ident = t.val; 
		if (!t.val.Equals("assembly") && ! t.val.Equals("module")) Error("global attribute target specifier \"assembly\" or \"module\" expected"); 
		Expect(87);
		tsym (t, depth); 
		Attribute(out attribute);
		gattrs.attributes.Add(attribute); 
		while (NotFinalComma()) {
			Expect(88);
			tsym (t, depth); 
			Attribute(out attribute);
			gattrs.attributes.Add(attribute); 
		}
		if (la.kind == 88) {
			Get();
			tsym (t, depth); 
		}
		Expect(114);
		tsym (t, depth); 
		lntsym (); --depth; 
	}

	void NamespaceMemberDeclaration(out ASTNamespaceMemberDecl nmd) {
		Modifiers m = new Modifiers (this);
		ASTExternAliasDirective	ead			= null;
		ASTUsing				au			= null;
		ASTAttributeGroups		attrGroups	= null;
		ASTAttributeGroup		attrGroup	= null;
		
		ntsym ("NamespaceMemberDeclaration", depth); ++depth; 
		nmd = null; 
		if (la.kind == 45) {
			nmd = new ASTNamespaceNamespace(); 
			Get();
			tsym (t, depth); 
			Expect(1);
			tsym (t, depth); 
			((ASTNamespaceNamespace)nmd).name = t.val; 
			while (la.kind == 91) {
				Get();
				tsym (t, depth); 
				((ASTNamespaceNamespace)nmd).name += t.val; 
				Expect(1);
				tsym (t, depth); 
				((ASTNamespaceNamespace)nmd).name += t.val; 
			}
			Expect(97);
			tsym (t, depth); 
			while (IsExternAliasDirective()) {
				ExternAliasDirective(out ead);
				((ASTNamespaceNamespace)nmd).externalAliasDirectives.Add (ead); 
			}
			while (la.kind == 78) {
				UsingDirective(out au);
				((ASTNamespaceNamespace)nmd).usings.Add (au); 
			}
			while (StartOf(1)) {
				ASTNamespaceMemberDecl nx; 
				NamespaceMemberDeclaration(out nx);
				((ASTNamespaceNamespace)nmd).namespaceMemberDecls.Add(nx); 
			}
			Expect(113);
			tsym (t, depth); 
			if (la.kind == 116) {
				Get();
				tsym (t, depth); 
			}
		} else if (StartOf(2)) {
			ASTNamespaceTypeDecl	typeDecl; 
			while (la.kind == 98) {
				if (null == attrGroups) attrGroups = new ASTAttributeGroups(); 
				Attributes(out attrGroup);
				attrGroups.Add (attrGroup); 
			}
			ModifierList(m);
			TypeDeclaration(m, attrGroups, out typeDecl);
			nmd = typeDecl; 
		} else SynErr(143);
		lntsym (); --depth; 
	}

	void TypeName(out ASTTypeName typeName) {
		typeName = new ASTTypeName(); string identif = ""; ASTTypeArgumentList targs = null; 
		ntsym ("TypeName", depth); 
		++depth; 
		Expect(1);
		tsym (t, depth); 
		identif = t.val; 
		if (la.kind == 92) {
			Get();
			tsym (t, depth); 
			identif += "::";  
			Expect(1);
			tsym (t, depth); 
			identif += t.val; 
		}
		if (la.kind == 101) {
			TypeArgumentList(out targs);
		}
		typeName.parts.Add (new ASTTypeNamePart(identif, targs)); 
		while (la.kind == 91) {
			Get();
			tsym (t, depth); 
			Expect(1);
			tsym (t, depth); 
			identif = t.val; 
			if (la.kind == 101) {
				TypeArgumentList(out targs);
			}
			typeName.parts.Add (new ASTTypeNamePart(identif, targs)); 
		}
		lntsym (); --depth; 
	}

	void Attributes(out ASTAttributeGroup attrGroup) {
		ntsym ("Attributes", depth); 
		++depth; 
		attrGroup = new ASTAttributeGroup(); 
		ASTAttribute attr; 
		Expect(98);
		tsym (t, depth); 
		if (IsAttrTargSpec()) {
			if (la.kind == 1) {
				Get();
				tsym (t, depth); 
				attrGroup.ident = t.val; 
			} else if (StartOf(3)) {
				Keyword();
				attrGroup.ident = t.val; 
			} else SynErr(144);
			Expect(87);
			tsym (t, depth); 
		}
		Attribute(out attr);
		attrGroup.attributes.Add(attr); 
		while (la.kind == _comma && Peek(1).kind != _rbrack) {
			Expect(88);
			tsym (t, depth); 
			Attribute(out attr);
			attrGroup.attributes.Add(attr); 
		}
		if (la.kind == 88) {
			Get();
			tsym (t, depth); 
		}
		Expect(114);
		tsym (t, depth); 
		lntsym (); --depth; 
	}

	void ModifierList(Modifiers m) {
		ntsym ("ModifierList", depth); 
		++depth; 
		while (StartOf(4)) {
			switch (la.kind) {
			case 46: {
				Get();
				tsym (t, depth); 
				m.Add(newMod		); 
				break;
			}
			case 55: {
				Get();
				tsym (t, depth); 
				m.Add(publicMod	); 
				break;
			}
			case 54: {
				Get();
				tsym (t, depth); 
				m.Add(protectedMod); 
				break;
			}
			case 41: {
				Get();
				tsym (t, depth); 
				m.Add(internalMod	); 
				break;
			}
			case 53: {
				Get();
				tsym (t, depth); 
				m.Add(privateMod	); 
				break;
			}
			case 76: {
				Get();
				tsym (t, depth); 
				m.Add(unsafeMod	); 
				break;
			}
			case 64: {
				Get();
				tsym (t, depth); 
				m.Add(staticMod	); 
				break;
			}
			case 56: {
				Get();
				tsym (t, depth); 
				m.Add(readonlyMod	); 
				break;
			}
			case 81: {
				Get();
				tsym (t, depth); 
				m.Add(volatileMod	); 
				break;
			}
			case 79: {
				Get();
				tsym (t, depth); 
				m.Add(virtualMod	); 
				break;
			}
			case 60: {
				Get();
				tsym (t, depth); 
				m.Add(sealedMod	); 
				break;
			}
			case 51: {
				Get();
				tsym (t, depth); 
				m.Add(overrideMod	); 
				break;
			}
			case 6: {
				Get();
				tsym (t, depth); 
				m.Add(abstractMod	); 
				break;
			}
			case 28: {
				Get();
				tsym (t, depth); 
				m.Add(externMod	); 
				break;
			}
			}
		}
		lntsym (); --depth; 
	}

	void TypeDeclaration(Modifiers m, ASTAttributeGroups attrGroups, out ASTNamespaceTypeDecl typeDecl) {
		TypeKind				dummy;
		ASTTypeName				typeName;
		ASTTypeParamList		typeParamList;
		ASTFormalParamList		formalParamList;
		
		ntsym ("TypeDeclaration", depth); 
		++depth; 
		typeDecl	= null; bool isPartial = false; 
		if (StartOf(5)) {
			if (la.kind == 1) {
				isPartial= true; 
				Get();
				tsym (t, depth); 
				if (!"partial".Equals(t.val)) { Error("partial expected, found: " + t.val); } 
			}
			if (la.kind == 16) {
				m.Check(classesMod); 
				typeDecl				= new ASTTypeDeclClass(); 
				typeDecl.modifiers	= m.getModifiers();	
				typeDecl.attrGroups	= attrGroups; 
				Get();
				tsym (t, depth); 
				((ASTTypeDeclClass)typeDecl).isPartial = isPartial; 
				Expect(1);
				tsym (t, depth); 
				((ASTTypeDeclClass)typeDecl).name = t.val; 
				if (la.kind == 101) {
					TypeParameterList(out typeParamList);
					((ASTTypeDeclClass)typeDecl).typeParamList.AddRange(typeParamList); 
				}
				if (la.kind == 87) {
					ASTTypeNames baseTypeNames = new ASTTypeNames(); 
					ClassBase(out baseTypeNames);
					((ASTTypeDeclClass)typeDecl).baseTypeNames.AddRange(baseTypeNames); 
				}
				while (la.kind == 1) {
					ASTTypeConstraint tcons; 
					TypeParameterConstraintsClause(out tcons);
					((ASTTypeDeclClass)typeDecl).constraints.Add(tcons); 
				}
				ClassBody(((ASTTypeDeclClass)typeDecl).members);
				if (la.kind == 116) {
					Get();
					tsym (t, depth); 
					typeDecl.hasFinalComma = true; 
				}
			} else if (la.kind == 66) {
				m.Check(nonClassTypesMod); 
				typeDecl = new ASTTypeDeclStruct (); 
				typeDecl.modifiers	= m.getModifiers(); 
				typeDecl.attrGroups	= attrGroups; 
				Get();
				tsym (t, depth); 
				((ASTTypeDeclStruct)typeDecl).isPartial	= isPartial;	
				Expect(1);
				tsym (t, depth); 
				((ASTTypeDeclStruct)typeDecl).name		= t.val;		
				if (la.kind == 101) {
					TypeParameterList(out typeParamList);
					((ASTTypeDeclStruct)typeDecl).typeParamList.AddRange(typeParamList); 
				}
				if (la.kind == 87) {
					Get();
					tsym (t, depth); 
					TypeName(out typeName);
					((ASTTypeDeclStruct)typeDecl).baseTypeNames.Add(typeName); 
					while (la.kind == 88) {
						Get();
						tsym (t, depth); 
						TypeName(out typeName);
						((ASTTypeDeclStruct)typeDecl).baseTypeNames.Add(typeName); 
					}
				}
				while (la.kind == 1) {
					ASTTypeConstraint tcons; 
					TypeParameterConstraintsClause(out tcons);
					((ASTTypeDeclStruct)typeDecl).constraints.Add(tcons); 
				}
				StructBody(((ASTTypeDeclStruct)typeDecl).members);
				if (la.kind == 116) {
					Get();
					tsym (t, depth); 
					typeDecl.hasFinalComma = true; 
				}
			} else if (la.kind == 40) {
				m.Check(nonClassTypesMod); 
				typeDecl = new ASTTypeDeclInterface (); 
				typeDecl.modifiers	= m.getModifiers(); 
				typeDecl.attrGroups	= attrGroups; 
				Get();
				tsym (t, depth); 
				((ASTTypeDeclInterface)typeDecl).isPartial	= isPartial;	
				Expect(1);
				tsym (t, depth); 
				((ASTTypeDeclInterface)typeDecl).name		= t.val;		
				if (la.kind == 101) {
					TypeParameterList(out typeParamList);
					((ASTTypeDeclInterface)typeDecl).typeParamList.AddRange(typeParamList); 
				}
				if (la.kind == 87) {
					Get();
					tsym (t, depth); 
					TypeName(out typeName);
					((ASTTypeDeclInterface)typeDecl).baseTypeNames.Add(typeName); 
					while (la.kind == 88) {
						Get();
						tsym (t, depth); 
						TypeName(out typeName);
						((ASTTypeDeclInterface)typeDecl).baseTypeNames.Add(typeName); 
					}
				}
				while (la.kind == 1) {
					ASTTypeConstraint tcons; 
					TypeParameterConstraintsClause(out tcons);
					((ASTTypeDeclInterface)typeDecl).constraints.Add(tcons); 
				}
				InterfaceBody(((ASTTypeDeclInterface)typeDecl).members);
				if (la.kind == 116) {
					Get();
					tsym (t, depth); 
					typeDecl.hasFinalComma = true; 
				}
			} else SynErr(145);
		} else if (la.kind == 25) {
			m.Check(nonClassTypesMod); 
			typeDecl = new ASTTypeDeclEnum (); 
			typeDecl.modifiers	= m.getModifiers(); 
			typeDecl.attrGroups	= attrGroups; 
			Get();
			tsym (t, depth); 
			Expect(1);
			tsym (t, depth); 
			((ASTTypeDeclEnum)typeDecl).name = t.val; 
			if (la.kind == 87) {
				Get();
				tsym (t, depth); 
				IntegralType(out typeName);
				((ASTTypeDeclEnum)typeDecl).baseType = typeName; 
			}
			EnumBody(((ASTTypeDeclEnum)typeDecl).members);
			if (la.kind == 116) {
				Get();
				tsym (t, depth); 
				typeDecl.hasFinalComma = true; 
			}
		} else if (la.kind == 21) {
			m.Check (nonClassTypesMod); 
			typeDecl = new ASTTypeDeclDelegate (); 
			typeDecl.modifiers	= m.getModifiers(); 
			typeDecl.attrGroups	= attrGroups; 
			Get();
			tsym (t, depth); 
			ASTType ty; 
			Type(out dummy, true, out ty);
			((ASTTypeDeclDelegate)typeDecl).returnType = ty;	
			Expect(1);
			tsym (t, depth); 
			((ASTTypeDeclDelegate)typeDecl).name	= t.val; 
			if (la.kind == 101) {
				TypeParameterList(out typeParamList);
				((ASTTypeDeclDelegate)typeDecl).typeParamList.AddRange(typeParamList); 
			}
			Expect(99);
			tsym (t, depth); 
			if (StartOf(6)) {
				formalParamList = new ASTFormalParamList(); 
				FormalParameterList(formalParamList);
				((ASTTypeDeclDelegate)typeDecl).formalParamList.AddRange(formalParamList); 
			}
			Expect(115);
			tsym (t, depth); 
			while (la.kind == 1) {
				ASTTypeConstraint tcons; 
				TypeParameterConstraintsClause(out tcons);
				((ASTTypeDeclDelegate)typeDecl).constraints.Add(tcons); 
			}
			Expect(116);
			tsym (t, depth); 
		} else SynErr(146);
		lntsym (); --depth; 
	}

	void TypeParameterList(out ASTTypeParamList tpl) {
		ntsym ("TypeParameterList", depth); 
		++depth; 
		tpl = new ASTTypeParamList(); ASTAttributeGroup attrGroup; 
		Expect(101);
		tsym (t, depth); 
		while (la.kind == 98) {
			Attributes(out attrGroup);
		}
		Expect(1);
		tsym (t, depth); 
		tpl.Add(new ASTTypeParam(t.val)); 
		while (la.kind == 88) {
			Get();
			tsym (t, depth); 
			while (la.kind == 98) {
				Attributes(out attrGroup);
			}
			Expect(1);
			tsym (t, depth); 
			tpl.Add(new ASTTypeParam(t.val)); 
		}
		Expect(94);
		tsym (t, depth); 
		lntsym (); --depth; 
	}

	void ClassBase(out ASTTypeNames baseTypeNames) {
		ASTTypeName typeName; baseTypeNames = new ASTTypeNames(); 
		ntsym ("ClassBase", depth); 
		++depth; 
		Expect(87);
		tsym (t, depth); 
		ClassType(out typeName);
		baseTypeNames.Add(typeName); 
		while (la.kind == 88) {
			Get();
			tsym (t, depth); 
			TypeName(out typeName);
			baseTypeNames.Add(typeName); 
		}
		lntsym (); --depth; 
	}

	void TypeParameterConstraintsClause(out ASTTypeConstraint tcons) {
		ASTTypeName typeName; 
		ntsym ("TypeParameterConstraintsClause", depth); 
		++depth; 
		Expect(1);
		tsym (t, depth); 
		if (! t.val.Equals("where")) { Error("type parameter constraints clause must start with: where"); } 
		Expect(1);
		tsym (t, depth); 
		tcons = new ASTTypeConstraint(); tcons.name = t.val;  
		Expect(87);
		tsym (t, depth); 
		if (StartOf(7)) {
			if (la.kind == 16) {
				Get();
				tsym (t, depth); 
				tcons.fixedConstraint = FixedConstraint.CLASS;  
			} else if (la.kind == 66) {
				Get();
				tsym (t, depth); 
				tcons.fixedConstraint = FixedConstraint.STRUCT; 
			} else if (la.kind == 48) {
				Get();
				tsym (t, depth); 
				tcons.fixedConstraint = FixedConstraint.OBJECT; 
			} else if (la.kind == 65) {
				Get();
				tsym (t, depth); 
				tcons.fixedConstraint = FixedConstraint.STRING; 
			} else {
				TypeName(out typeName);
				tcons.typeNames.Add(typeName); 
			}
			while (la.kind == _comma && Peek(1).kind != _new) {
				Expect(88);
				tsym (t, depth); 
				TypeName(out typeName);
				tcons.typeNames.Add(typeName); 
			}
			if (la.kind == 88) {
				tcons.hasNewConstraint = true; 
				Get();
				tsym (t, depth); 
				Expect(46);
				tsym (t, depth); 
				Expect(99);
				tsym (t, depth); 
				Expect(115);
				tsym (t, depth); 
			}
		} else if (la.kind == 46) {
			tcons.hasNewConstraint = true; 
			Get();
			tsym (t, depth); 
			Expect(99);
			tsym (t, depth); 
			Expect(115);
			tsym (t, depth); 
		} else SynErr(147);
		lntsym (); --depth; 
	}

	void ClassBody(ASTMemberDecls members) {
		ntsym ("ClassBody", depth); 
		++depth; 
		ASTAttributeGroups	attrGroups	= null; 
		ASTAttributeGroup	attrGroup	= null; 
		Expect(97);
		tsym (t, depth); 
		while (StartOf(8)) {
			while (la.kind == 98) {
				if (null == attrGroups) attrGroups = new ASTAttributeGroups(); 
				Attributes(out attrGroup);
				attrGroups.Add (attrGroup); 
			}
			Modifiers m = new Modifiers(this); 
			ModifierList(m);
			ASTMemberDecl smd; 
			ClassMemberDeclaration(m, attrGroups, out smd);
			members.Add(smd);  
			attrGroups = null; 
		}
		Expect(113);
		tsym (t, depth); 
		lntsym (); --depth; 
	}

	void StructBody(ASTMemberDecls members) {
		ntsym ("StructBody", depth); 
		++depth; 
		ASTAttributeGroups	attrGroups	= null; 
		ASTAttributeGroup	attrGroup	= null; 
		Expect(97);
		tsym (t, depth); 
		while (StartOf(9)) {
			while (la.kind == 98) {
				if (null == attrGroups) attrGroups = new ASTAttributeGroups(); 
				Attributes(out attrGroup);
				attrGroups.Add (attrGroup); 
			}
			Modifiers m = new Modifiers(this); 
			ModifierList(m);
			ASTMemberDecl smd; 
			StructMemberDeclaration(m, attrGroups, out smd);
			members.Add(smd);  
			attrGroups = null; 
		}
		Expect(113);
		tsym (t, depth);		
		lntsym (); --depth;	
	}

	void InterfaceBody(ASTMemberDeclsI members) {
		ntsym ("InterfaceBody", depth); 
		++depth; 
		Expect(97);
		tsym (t, depth); 
		while (StartOf(10)) {
			InterfaceMemberDeclaration(members);
		}
		Expect(113);
		tsym (t, depth); 
		lntsym (); -- depth; 
	}

	void IntegralType(out ASTTypeName typeName) {
		ntsym ("IntegralType", depth); 
		++depth; 
		switch (la.kind) {
		case 59: {
			Get();
			break;
		}
		case 11: {
			Get();
			break;
		}
		case 61: {
			Get();
			break;
		}
		case 77: {
			Get();
			break;
		}
		case 39: {
			Get();
			break;
		}
		case 73: {
			Get();
			break;
		}
		case 44: {
			Get();
			break;
		}
		case 74: {
			Get();
			break;
		}
		case 14: {
			Get();
			break;
		}
		default: SynErr(148); break;
		}
		typeName = new ASTTypeName (t.val); 
		tsym (t, depth);		
		lntsym (); --depth;	
	}

	void EnumBody(ASTEnumMemberDecls enumMembers) {
		ntsym ("EnumBody", depth); 
		++depth; 
		ASTEnumMemberDecl enumMember = null; 
		Expect(97);
		tsym (t, depth); 
		if (la.kind == 1 || la.kind == 98) {
			EnumMemberDeclaration(out enumMember);
			enumMembers.Add (enumMember); 
			while (NotFinalComma()) {
				Expect(88);
				tsym (t, depth);		
				EnumMemberDeclaration(out enumMember);
				enumMembers.Add (enumMember); 
			}
			if (la.kind == 88) {
				Get();
				tsym (t, depth); 
				enumMembers.hasFinalComma = true; 
			}
		}
		Expect(113);
		tsym (t, depth);		
		lntsym (); --depth;	
	}

	void Type(out TypeKind type, bool voidAllowed, out ASTType ty) {
		type= TypeKind.simple;	
		ty	= new ASTType();
		ASTTypeName typeName = null;
		
		ntsym ("Type", depth); 
		++depth; 
		if (StartOf(11)) {
			PrimitiveType(out typeName);
			ty.typeKind = ASTTypeKind.Primitive; ty.typeName = typeName; 
		} else if (la.kind == 1 || la.kind == 48 || la.kind == 65) {
			ClassType(out typeName);
			ty.typeKind = ASTTypeKind.Class;		ty.typeName = typeName; 
		} else if (la.kind == 80) {
			Get();
			ty.typeKind = ASTTypeKind.Void;		ty.typeName = new ASTTypeName("void"); 
			tsym (t, depth); 
			type = TypeKind.@void; 
		} else SynErr(149);
		if (la.kind == 112) {
			Get();
			ty.isNullable = true; 
			tsym (t, depth); 
			if (type == TypeKind.@void) { Error("Unexpected token ?, void must not be nullable."); } 
		}
		PointerOrArray(out type, type, ty);
		if (type == TypeKind.@void && !voidAllowed) { Error("type expected, void found, maybe you mean void*"); } 
		lntsym (); --depth; 
	}

	void FormalParameterList(ASTFormalParamList fpl) {
		TypeKind			type;
		ASTType				ty			= null;
		string				sIdent		= "";
		FormalParamModif	modif		= FormalParamModif._;
		ASTAttributeGroups  attrGroups  = new ASTAttributeGroups();
		
		ntsym ("FormalParameterList", depth);
		++depth; 
		while (la.kind == 98) {
			ASTAttributeGroup attrGroup = null;	
			Attributes(out attrGroup);
			attrGroups.Add (attrGroup);			
		}
		if ("__arglist".Equals(la.val)) {
			Expect(1);
			tsym (t, depth); 
			modif = FormalParamModif.ARGLIST;
			ASTFormalParam fp = new ASTFormalParam (modif, ty, sIdent);
			if (null != attrGroups) { fp.attrGroups.AddRange (attrGroups); }
			fpl.Add (fp);
			
		} else if (StartOf(12)) {
			if (la.kind == 50 || la.kind == 57 || la.kind == 68) {
				if (la.kind == 57) {
					Get();
					tsym (t, depth); 
					modif = FormalParamModif.REF;	
				} else if (la.kind == 50) {
					Get();
					tsym (t, depth); 
					modif = FormalParamModif.OUT;	
				} else {
					Get();
					tsym (t, depth); 
					modif = FormalParamModif.THIS;	
				}
			}
			Type(out type, false, out ty);
			Expect(1);
			tsym (t, depth); 
			sIdent = t.val; 
			ASTFormalParam fp = new ASTFormalParam (modif, ty, sIdent);
			if (null != attrGroups) { fp.attrGroups.AddRange (attrGroups); }
			fpl.Add (fp);
			
			if (la.kind == 88) {
				Get();
				tsym (t, depth); 
				FormalParameterList(fpl);
			}
		} else if (la.kind == 52) {
			Get();
			tsym (t, depth); 
			modif = FormalParamModif.PARAMS; 
			Type(out type, false, out ty);
			if (type != TypeKind.array) { Error("params argument must be an array"); } 
			Expect(1);
			tsym (t, depth); 
			sIdent = t.val; 
			ASTFormalParam fp = new ASTFormalParam (modif, ty, sIdent);
			if (null != attrGroups) { fp.attrGroups.AddRange (attrGroups); }
			fpl.Add (fp);
			
		} else SynErr(150);
		lntsym (); --depth; 
	}

	void ClassType(out ASTTypeName typeName) {
		ntsym ("ClassType", depth); 
		++depth; 
		typeName = null; 
		if (la.kind == 1) {
			TypeName(out typeName);
		} else if (la.kind == 48 || la.kind == 65) {
			InternalClassType(out typeName);
		} else SynErr(151);
		lntsym (); --depth; 
	}

	void ClassMemberDeclaration(Modifiers m, ASTAttributeGroups attrGroups, out ASTMemberDecl smd) {
		ntsym ("ClassMemberDeclaration", depth); 
		++depth; 
		smd = null; 
		ASTBlock block; 
		if (StartOf(13)) {
			StructMemberDeclaration(m, attrGroups, out smd);
		} else if (la.kind == 117) {
			smd = new ASTMemberDeclDtor(); 
			((ASTMemberDeclDtor)smd).modifiers = m.getModifiers(); 
			if (null != attrGroups) ((ASTMemberDeclDtor)smd).attrGroups.AddRange(attrGroups); 
			Get();
			tsym (t, depth); 
			Expect(1);
			tsym (t, depth); 
			((ASTMemberDeclDtor)smd).name = t.val; 
			Expect(99);
			tsym (t, depth); 
			Expect(115);
			tsym (t, depth); 
			if (la.kind == 97) {
				Block(out block);
				((ASTMemberDeclDtor)smd).block = block; 
			} else if (la.kind == 116) {
				Get();
				tsym (t, depth); 
			} else SynErr(152);
		} else SynErr(153);
		lntsym (); --depth; 
	}

	void InterfaceMemberDeclaration(ASTMemberDeclsI members) {
		Modifiers m = new Modifiers(this);
		                                      m.Add (Parser.publicMod);	// every interface member is public
		                                      TypeKind			dummy;
		                                      bool				newSet		= false;
		ASTType				ty			= null;
		ASTTypeParamList	tpl			= null;
		ASTAttributeGroup	attrGroup	= null;
		ASTAttributeGroups	attrGroups	= null;
		ASTTypeConstraint	tcons		= null;
		                                  
		ntsym ("InterfaceMemberDeclaration", depth); 
		++depth; 
		while (la.kind == 98) {
			if (null == attrGroups) attrGroups = new ASTAttributeGroups(); 
			Attributes(out attrGroup);
			attrGroups.Add(attrGroup); 
		}
		if (la.kind == 46) {
			Get();
			tsym (t, depth); 
			m.Add(Parser.newMod); newSet = true; 
		}
		if (StartOf(14)) {
			if (la.kind == 76) {
				Get();
				tsym (t, depth); 
				m.Add(Parser.unsafeMod); 
			}
			if (la.kind == 46) {
				Get();
				tsym (t, depth); 
				if (newSet) Error("duplicate operand 'new'"); m.Add(Parser.newMod); 
			}
			Type(out dummy, true, out ty);
			if (la.kind == 1) {
				Get();
				tsym (t, depth); 
				string sIdent = t.val; 
				if (la.kind == 99 || la.kind == 101) {
					ASTMemberDeclMethodI member = new ASTMemberDeclMethodI(); 
					if (null != attrGroups) member.attrGroups.AddRange(attrGroups); 
					member.modifiers = m.getModifiers(); member.type	= ty; member.ident= sIdent; 
					if (la.kind == 101) {
						TypeParameterList(out tpl);
						member.typeParamList.AddRange(tpl); 
					}
					Expect(99);
					tsym (t, depth); 
					if (StartOf(6)) {
						FormalParameterList(member.formalParamList);
					}
					Expect(115);
					tsym (t, depth); 
					while (la.kind == 1) {
						TypeParameterConstraintsClause(out tcons);
						member.constraints.Add (tcons); 
					}
					members.Add(member); 
					Expect(116);
					tsym (t, depth); 
				} else if (la.kind == 97) {
					ASTMemberDeclPropertyI	member = new ASTMemberDeclPropertyI(); 
					if (null != attrGroups)	member.attrGroups.AddRange(attrGroups); 
					member.modifiers = m.getModifiers(); member.type	= ty; member.ident= sIdent; 
					Get();
					tsym (t, depth); 
					InterfaceAccessors(m, member.accessors);
					Expect(113);
					tsym (t, depth); 
					members.Add(member); 
				} else SynErr(154);
			} else if (la.kind == 68) {
				ASTMemberDeclIndexerI	member = new ASTMemberDeclIndexerI(); 
				if (null != attrGroups)	member.attrGroups.AddRange(attrGroups); 
				member.modifiers = m.getModifiers(); 
				Get();
				tsym (t, depth); 
				Expect(98);
				tsym (t, depth); 
				FormalParameterList(member.formalParamList);
				Expect(114);
				tsym (t, depth); 
				Expect(97);
				tsym (t, depth); 
				InterfaceAccessors(m, member.accessors);
				Expect(113);
				tsym (t, depth); 
				members.Add(member); 
			} else SynErr(155);
		} else if (la.kind == 26) {
			ASTMemberDeclEventI member = new ASTMemberDeclEventI(); 
			Get();
			tsym (t, depth); 
			if (null != attrGroups) member.attrGroups.AddRange(attrGroups); 
			Type(out dummy, false, out ty);
			member.modifiers = m.getModifiers(); member.type = ty; 
			Expect(1);
			tsym (t, depth); 
			member.ident = t.val; 
			Expect(116);
			tsym (t, depth); 
			members.Add (member); 
		} else SynErr(156);
		lntsym (); --depth; 
	}

	void StructMemberDeclaration(Modifiers m, ASTAttributeGroups attrGroups, out ASTMemberDecl smd) {
		TypeKind			type;
		int					op;
		ASTTypeName			typeName;
		ASTType				ty;
		ASTMemberName		memberName;
		ASTTypeParamList	tpl;
		ASTFormalParamList	fpl;
		ASTExpr		expr;
		ASTBlock			block;
		
		ntsym ("StructMemberDeclaration", depth); 
		++depth; 
		smd = null; 
		if (la.kind == 17) {
			m.Check(constantsMod); 
			smd = new ASTMemberDeclConst(); string sIdent = ""; 
			if (null != attrGroups) smd.attrGroups.AddRange(attrGroups);	
			((ASTMemberDeclConst)smd).modifiers = m.getModifiers();
			
			Get();
			tsym (t, depth); 
			Type(out type, false, out ty);
			((ASTMemberDeclConst)smd).type = ty; 
			Expect(1);
			tsym (t, depth); 
			sIdent = t.val; 
			Expect(86);
			tsym (t, depth); 
			Expression(out expr);
			((ASTMemberDeclConst)smd).initializers.Add(new ASTConstInitializer(sIdent, expr)); 
			while (la.kind == 88) {
				Get();
				tsym (t, depth); 
				Expect(1);
				tsym (t, depth); 
				sIdent = t.val; 
				Expect(86);
				tsym (t, depth); 
				Expression(out expr);
				((ASTMemberDeclConst)smd).initializers.Add(new ASTConstInitializer(sIdent, expr)); 
			}
			Expect(116);
			tsym (t, depth); 
		} else if (la.kind == 26) {
			m.Check(propEvntMethsMod); 
			Get();
			tsym (t, depth); 
			Type(out type, false, out ty);
			if (IsFieldDecl()) {
				smd = new ASTMemberDeclEventNormal(); 
				if (null != attrGroups) smd.attrGroups.AddRange (attrGroups);
				((ASTMemberDeclEventNormal)smd).modifiers = m.getModifiers ();
				((ASTMemberDeclEventNormal)smd).type			= ty;
				
				VariableDeclarators(m, ((ASTMemberDeclEventNormal)smd).variableDeclarators);
				Expect(116);
				tsym (t, depth); 
			} else if (la.kind == 1) {
				smd = new ASTMemberDeclEventAccessors(); 
				if (null != attrGroups) smd.attrGroups.AddRange (attrGroups);
				((ASTMemberDeclEventAccessors)smd).modifiers	= m.getModifiers();
				((ASTMemberDeclEventAccessors)smd).type		= ty;
				
				TypeName(out typeName);
				((ASTMemberDeclEventAccessors)smd).typeName	= typeName; 
				Expect(97);
				tsym (t, depth); 
				EventAccessorDeclarations(((ASTMemberDeclEventAccessors)smd).accessorDecls);
				Expect(113);
				tsym (t, depth); 
			} else SynErr(157);
		} else if (kindInContext(la.kind) == _ident && Peek(1).kind == _lpar) {
			m.Check(constructorsMod|staticConstrMod); 
			smd = new ASTMemberDeclCtor();
			if (null != attrGroups ) smd.attrGroups.AddRange(attrGroups);
			((ASTMemberDeclCtor)smd).modifiers = m.getModifiers();
			ASTArgument argument = null;
			
			Expect(1);
			tsym (t, depth); 
			((ASTMemberDeclCtor)smd).ident = t.val; 
			Expect(99);
			tsym (t, depth); 
			if (StartOf(6)) {
				m.Check (constructorsMod); 
				FormalParameterList(((ASTMemberDeclCtor)smd).fpl);
			}
			Expect(115);
			tsym (t, depth); 
			if (la.kind == 87) {
				m.Check(constructorsMod); 
				Get();
				tsym (t, depth); 
				if (la.kind == 8) {
					Get();
					tsym (t, depth); 
					((ASTMemberDeclCtor)smd).hasBaseCall = true; 
				} else if (la.kind == 68) {
					Get();
					tsym (t, depth); 
					((ASTMemberDeclCtor)smd).hasThisCall = true; 
				} else SynErr(158);
				Expect(99);
				tsym (t, depth); 
				if (StartOf(15)) {
					Argument(out argument);
					((ASTMemberDeclCtor)smd).arguments.Add(argument); 
					while (la.kind == 88) {
						Get();
						tsym (t, depth); 
						Argument(out argument);
						((ASTMemberDeclCtor)smd).arguments.Add(argument); 
					}
				}
				Expect(115);
				tsym (t, depth); 
			} else if (la.kind == 97 || la.kind == 116) {
			} else SynErr(159);
			if (la.kind == 97) {
				Block(out block);
				((ASTMemberDeclCtor)smd).block = block; 
			} else if (la.kind == 116) {
				Get();
				tsym (t, depth); 
			} else SynErr(160);
		} else if (la.kind == 31) {
			smd = new ASTMemberDeclFixedBuffer(); 
			Get();
			tsym (t, depth); 
			((ASTMemberDeclFixedBuffer)smd).modifiers = m.getModifiers(); if (null != attrGroups ) smd.attrGroups.AddRange(attrGroups); 
			Type(out type, true, out ty);
			((ASTMemberDeclFixedBuffer)smd).type	= ty;		
			Expect(1);
			tsym (t, depth); 
			((ASTMemberDeclFixedBuffer)smd).ident= t.val;	
			Expect(98);
			tsym (t, depth); 
			Expression(out expr);
			((ASTMemberDeclFixedBuffer)smd).expression= expr;
			Expect(114);
			tsym (t, depth); 
			Expect(116);
			tsym (t, depth); 
		} else if (IsTypeDeclaration()) {
			ASTNamespaceTypeDecl typeDecl = null;
			smd = new ASTMemberDeclTypeDecl (); 
			((ASTMemberDeclTypeDecl) smd).modifiers = m.getModifiers ();
			if (null != attrGroups ) smd.attrGroups.AddRange(attrGroups);
			
			TypeDeclaration(m, attrGroups, out typeDecl);
			((ASTMemberDeclTypeDecl)smd).typeDecl = typeDecl; 
		} else if (StartOf(16)) {
			bool isPartial = false; 
			if ("partial".Equals(la.val)) {
				Expect(1);
				tsym (t, depth); 
				isPartial = true; 
			}
			Type(out type, true, out ty);
			if (la.kind == 49) {
				m.Check(operatorsMod); m.CheckMust(operatorsMustMod); if (type == TypeKind.@void) { Error("operator not allowed on void"); } 
				smd = new ASTMemberDeclOperator(); 
				((ASTMemberDeclOperator)smd).modifiers	= m.getModifiers(); if (null != attrGroups ) smd.attrGroups.AddRange(attrGroups); 
				((ASTMemberDeclOperator)smd).type		= ty; 
				((ASTMemberDeclOperator)smd).isPartial	= isPartial; 
				Get();
				tsym (t, depth); 
				OverloadableOp(out op);
				((ASTMemberDeclOperator)smd).overOp	= op; 
				Expect(99);
				tsym (t, depth); 
				Type(out type, false, out ty);
				Expect(1);
				tsym (t, depth); 
				((ASTMemberDeclOperator)smd).fpl.Add(new ASTFormalParam(FormalParamModif._, ty, t.val)); 
				if (la.kind == 88) {
					Get();
					tsym (t, depth); 
					Type(out type, false, out ty);
					if ((op & binaryOp) == 0) Error("too many operands for unary operator"); 
					Expect(1);
					tsym (t, depth); 
					((ASTMemberDeclOperator)smd).fpl.Add(new ASTFormalParam(FormalParamModif._, ty, t.val)); 
				} else if (la.kind == 115) {
					if ((op & unaryOp) == 0) Error("too few operands for binary operator"); 
				} else SynErr(161);
				Expect(115);
				tsym (t, depth); 
				if (la.kind == 97) {
					Block(out block);
					((ASTMemberDeclOperator)smd).block	= block; 
				} else if (la.kind == 116) {
					Get();
					tsym (t, depth); 
				} else SynErr(162);
			} else if (IsFieldDecl()) {
				m.Check (fieldsMod); if (type == TypeKind.@void) { Error("field type must not be void"); } 
				smd = new ASTMemberDeclField(); 
				if (null != attrGroups ) smd.attrGroups.AddRange(attrGroups);
				((ASTMemberDeclField)smd).type = ty;
				((ASTMemberDeclField)smd).modifiers = m.getModifiers();
				((ASTMemberDeclField)smd).isPartial = isPartial;
				
				VariableDeclarators(m, ((ASTMemberDeclField)smd).variableDeclarators);
				Expect(116);
				tsym (t, depth); 
			} else if (la.kind == 1) {
				MemberName(out memberName);
				if (la.kind == 97) {
					m.Check(propEvntMethsMod); if (type == TypeKind.@void) { Error("property type must not be void"); } 
					smd = new ASTMemberDeclProperty(); if (null != attrGroups) smd.attrGroups.AddRange(attrGroups); 
					((ASTMemberDeclProperty)smd).modifiers	= m.getModifiers();	
					((ASTMemberDeclProperty)smd).type		= ty;				
					((ASTMemberDeclProperty)smd).name		= memberName;		
					((ASTMemberDeclProperty)smd).isPartial	= isPartial;		
					Get();
					tsym (t, depth); 
					AccessorDeclarations(m, ((ASTMemberDeclProperty)smd).accesorDeclarations);
					Expect(113);
					tsym (t, depth); 
				} else if (la.kind == 91) {
					m.Check(indexersMod); if (type == TypeKind.@void) { Error("indexer type must not be void"); } 
					smd = new ASTMemberDeclIndexer(); 
					((ASTMemberDeclIndexer)smd).modifiers= m.getModifiers(); if (null != attrGroups) smd.attrGroups.AddRange(attrGroups); 
					((ASTMemberDeclIndexer)smd).isPartial= isPartial;	
					((ASTMemberDeclIndexer)smd).type		= ty;			
					((ASTMemberDeclIndexer)smd).name		=memberName;	
					Get();
					tsym (t, depth); 
					Expect(68);
					tsym (t, depth); 
					Expect(98);
					tsym (t, depth); 
					fpl = new ASTFormalParamList(); 
					FormalParameterList(fpl);
					((ASTMemberDeclIndexer)smd).formalParamList.AddRange(fpl); 
					Expect(114);
					tsym (t, depth); 
					Expect(97);
					tsym (t, depth); 
					AccessorDeclarations(m, ((ASTMemberDeclIndexer)smd).accesorDeclarations);
					Expect(113);
					tsym (t, depth); 
				} else if (la.kind == 99 || la.kind == 101) {
					m.Check(propEvntMethsMod); 
					smd = new ASTMemberDeclMethod(); 
					((ASTMemberDeclMethod)smd).modifiers	= m.getModifiers(); if (null != attrGroups) smd.attrGroups.AddRange(attrGroups); 
					((ASTMemberDeclMethod)smd).returnType= ty; 
					((ASTMemberDeclMethod)smd).name		= memberName; 
					((ASTMemberDeclMethod)smd).isPartial	= isPartial; 
					if (la.kind == 101) {
						TypeParameterList(out tpl);
						((ASTMemberDeclMethod)smd).typeParamList.AddRange(tpl); 
					}
					Expect(99);
					tsym (t, depth); 
					if (StartOf(6)) {
						fpl = new ASTFormalParamList(); 
						FormalParameterList(fpl);
						((ASTMemberDeclMethod)smd).formalParamList.AddRange(fpl); 
					}
					Expect(115);
					tsym (t, depth); 
					while (la.kind == 1) {
						ASTTypeConstraint tcons; 
						TypeParameterConstraintsClause(out tcons);
						((ASTMemberDeclMethod)smd).constraints.Add(tcons); 
					}
					if (la.kind == 97) {
						Block(out block);
						((ASTMemberDeclMethod)smd).block = block; 
					} else if (la.kind == 116) {
						Get();
						tsym (t, depth); 
					} else SynErr(163);
				} else SynErr(164);
			} else if (la.kind == 68) {
				m.Check(indexersMod); if (type == TypeKind.@void) { Error("indexer type must not be void"); } 
				smd = new ASTMemberDeclIndexer(); 
				((ASTMemberDeclIndexer)smd).modifiers= m.getModifiers(); if (null != attrGroups) smd.attrGroups.AddRange(attrGroups); 
				((ASTMemberDeclIndexer)smd).isPartial= isPartial;	
				((ASTMemberDeclIndexer)smd).type		= ty;			
				Get();
				tsym (t, depth); 
				Expect(98);
				tsym (t, depth); 
				fpl = new ASTFormalParamList(); 
				FormalParameterList(fpl);
				((ASTMemberDeclIndexer)smd).formalParamList.AddRange(fpl); 
				Expect(114);
				tsym (t, depth); 
				Expect(97);
				tsym (t, depth); 
				AccessorDeclarations(m, ((ASTMemberDeclIndexer)smd).accesorDeclarations);
				Expect(113);
				tsym (t, depth); 
			} else SynErr(165);
		} else if (la.kind == 27 || la.kind == 37) {
			m.Check(operatorsMod); m.CheckMust(operatorsMustMod); 
			smd = new ASTMemberDeclCastOperator(); if (null != attrGroups) smd.attrGroups.AddRange(attrGroups); 
			((ASTMemberDeclCastOperator)smd).modifiers = m.getModifiers(); 
			if (la.kind == 37) {
				Get();
				tsym (t, depth); 
				((ASTMemberDeclCastOperator)smd).isExplicit = false; 
			} else {
				Get();
				tsym (t, depth); 
				((ASTMemberDeclCastOperator)smd).isExplicit = true ; 
			}
			Expect(49);
			tsym (t, depth); 
			Type(out type, false, out ty);
			if (type == TypeKind.@void) { Error("cast type must not be void"); } 
			((ASTMemberDeclCastOperator)smd).type = ty; 
			Expect(99);
			tsym (t, depth); 
			Type(out type, false, out ty);
			Expect(1);
			tsym (t, depth); 
			((ASTMemberDeclCastOperator)smd).param = new ASTFormalParam(ty, t.val); 
			Expect(115);
			tsym (t, depth); 
			if (la.kind == 97) {
				Block(out block);
				((ASTMemberDeclCastOperator)smd).block = block; 
			} else if (la.kind == 116) {
				Get();
				tsym (t, depth); 
			} else SynErr(166);
		} else SynErr(167);
		lntsym (); --depth; 
	}

	void EnumMemberDeclaration(out ASTEnumMemberDecl enumMember) {
		ntsym ("InterfaceMemberDeclaration", depth); 
		++depth; 
		ASTExpr expr ; ASTAttributeGroup attrGroup = null; enumMember = new ASTEnumMemberDecl(); 
		while (la.kind == 98) {
			Attributes(out attrGroup);
			enumMember.attrGroups.Add (attrGroup); 
		}
		Expect(1);
		tsym (t, depth); 
		enumMember.ident = t.val; 
		if (la.kind == 86) {
			Get();
			tsym (t, depth); 
			Expression(out expr);
			enumMember.expression = expr; 
		}
		lntsym (); --depth; 
	}

	void Block(out ASTBlock block) {
		ntsym ("Block", depth); 
		++depth; 
		ASTStatement stmt; block = new ASTBlock(); 
		Expect(97);
		tsym (t, depth); 
		while (StartOf(17)) {
			Statement(out stmt);
			block.stmts.Add (stmt); 
		}
		Expect(113);
		tsym (t, depth); 
		lntsym (); --depth; 
	}

	void Expression(out ASTExpr expr) {
		ntsym ("Expression", depth); 
		++depth; 
		checkForContextSwitch(); 
		ASTExpr exprx ; expr = null; ASTBlock block; 
		expr = new ASTExpr(); 
		if (la.kind == 123) {
			QueryExpression();
		} else if (IsImplicitTypedLambdaExpression()) {
			ImplicitLambdaExpression();
		} else if (IsExplicitTypedLambdaExpression()) {
			expr = new ASTExprExplicitTypedLambda(); 
			Expect(99);
			tsym (t, depth); 
			if (StartOf(18)) {
				ASTAnonMethodParam amp; 
				AnonymousMethodParameter(out amp);
				((ASTExprExplicitTypedLambda)expr).parameters.Add(amp); 
				while (la.kind == 88) {
					Get();
					tsym (t, depth); 
					AnonymousMethodParameter(out amp);
					((ASTExprExplicitTypedLambda)expr).parameters.Add(amp); 
				}
			}
			Expect(115);
			tsym (t, depth); 
			Expect(85);
			tsym (t, depth); 
			if (la.kind == 97) {
				Block(out block);
				((ASTExprExplicitTypedLambda)expr).exprBody = block; 
			} else if (StartOf(19)) {
				Expression(out exprx);
				((ASTExprExplicitTypedLambda)expr).exprBody = exprx; 
			} else SynErr(168);
		} else if (StartOf(20)) {
			ASTExprUnary exprUnary; 
			Unary(out exprUnary);
			expr = new ASTExprBinaryExpr(); ((ASTExprBinaryExpr)expr).left=exprUnary; 
			if (assgnOps[kindInContext(la.kind)] || (la.kind == _gt && Peek(1).kind == _gteq)) {
				string sop = ""; 
				AssignmentOperator(out sop);
				((ASTExprBinaryExpr)expr).op		= sop; 
				Expression(out exprx);
				((ASTExprBinaryExpr)expr).right	= exprx;
			} else if (StartOf(21)) {
				NullCoalescingExpr(out exprx);
				((ASTExprBinaryExpr)expr).right	= exprx;
				if (la.kind == 112) {
					Get();
					tsym (t, depth); 
					Expression(out exprx);
					expr = new ASTExprBinaryExpr (expr, "?", exprx); 
					Expect(87);
					tsym (t, depth); 
					Expression(out exprx);
					expr = new ASTExprBinaryExpr (expr, ":", exprx); 
				}
			} else SynErr(169);
		} else SynErr(170);
		lntsym (); --depth; 
	}

	void VariableDeclarators(Modifiers m, ASTVariableDeclarators variableDeclarators) {
		ntsym ("VariableDeclarators", depth); 
		++depth; 
		ASTVariableDeclarator  varDecl; 
		ASTVariableInitializer varInitializer; 
		Expect(1);
		tsym (t, depth); 
		varDecl = new ASTVariableDeclarator(); varDecl.ident = t.val; 
		if (la.kind == 86) {
			Get();
			tsym (t, depth); 
			VariableInitializer(out varInitializer);
			varDecl.varInitializer = varInitializer; 
		}
		variableDeclarators.Add (varDecl); 
		while (la.kind == 88) {
			Get();
			tsym (t, depth); 
			Expect(1);
			tsym (t, depth); 
			varDecl = new ASTVariableDeclarator(); varDecl.ident = t.val; 
			if (la.kind == 86) {
				Get();
				tsym (t, depth); 
				VariableInitializer(out varInitializer);
				varDecl.varInitializer = varInitializer; 
			}
			variableDeclarators.Add (varDecl); 
		}
		lntsym (); --depth; 
	}

	void EventAccessorDeclarations(ASTAccessorEvents accessorDecls) {
		bool addFound = false, remFound = false; 
		ntsym ("EventAccessorDeclarations", depth); 
		++depth; 
		ASTAttributeGroup 		attrGroup	= null;
		ASTAttributeGroups		attrGroups	= null;
		ASTBlock				block		= null;
		ASTAccessorEvent		accessor1	= null, accessor2 = null;
		
		while (la.kind == 98) {
			if (null == attrGroups) attrGroups = new ASTAttributeGroups(); 
			Attributes(out attrGroup);
			attrGroups.Add ( attrGroup ); 
		}
		if (la.val.Equals("add"   )) {
			Expect(1);
			tsym (t, depth); 
			addFound = true; accessor1 = new ASTAccessorEventAdd		(); if (null != attrGroups) accessor1.attrGroups.AddRange(attrGroups); 
		} else if (la.val.Equals("remove")) {
			Expect(1);
			tsym (t, depth); 
			remFound = true; accessor1 = new ASTAccessorEventRemove	(); if (null != attrGroups) accessor1.attrGroups.AddRange(attrGroups); 
		} else if (la.kind == 1) {
			Get();
			tsym (t, depth); 
			Error("add or remove expected"); 
		} else SynErr(171);
		Block(out block);
		if (accessor1 != null) { accessor1.block = block; accessorDecls.Add(accessor1); } 
		if (la.kind == 1 || la.kind == 98) {
			attrGroups = null; 
			while (la.kind == 98) {
				if (null == attrGroups) attrGroups = new ASTAttributeGroups(); 
				Attributes(out attrGroup);
				attrGroups.Add ( attrGroup ); 
			}
			if (la.val.Equals("add"   )) {
				Expect(1);
				tsym (t, depth); 
				if (addFound) Error("add already declared"   ); else { addFound = true; remFound = false; } 
				accessor2 = new ASTAccessorEventAdd		(); if (null != attrGroups) accessor2.attrGroups.AddRange(attrGroups); 
			} else if (la.val.Equals("remove")) {
				Expect(1);
				tsym (t, depth); 
				if (remFound) Error("remove already declared"); else { remFound = true; addFound = false; } 
				accessor2 = new ASTAccessorEventRemove	(); if (null != attrGroups) accessor2.attrGroups.AddRange(attrGroups); 
			} else if (la.kind == 1) {
				Get();
				tsym (t, depth); 
				addFound = false; remFound = false; Error("add or remove expected"); 
			} else SynErr(172);
			Block(out block);
			if (accessor2 != null) { accessor2.block = block; accessorDecls.Add(accessor2); }  
		}
		lntsym (); --depth; 
	}

	void Argument(out ASTArgument argument) {
		ntsym ("Argument", depth); 
		++depth; 
		ASTExpr expr ; 
		argument = new ASTArgument(); 
		if (la.kind == 50 || la.kind == 57) {
			if (la.kind == 57) {
				Get();
				tsym (t, depth); argument.isRef = true; 
			} else {
				Get();
				tsym (t, depth); argument.isOut = true; 
			}
		}
		Expression(out expr);
		argument.expression = expr; 
		lntsym (); --depth; 
	}

	void OverloadableOp(out int op) {
		op = plusOp; 
		ntsym ("OverloadableOp", depth); 
		++depth; 
		switch (la.kind) {
		case 110: {
			Get();
			tsym (t, depth); 
			break;
		}
		case 103: {
			Get();
			tsym (t, depth); 
			op = minusOp;	
			break;
		}
		case 107: {
			Get();
			tsym (t, depth); 
			op = notOp;	
			break;
		}
		case 117: {
			Get();
			tsym (t, depth); 
			op = tildeOp;	
			break;
		}
		case 96: {
			Get();
			tsym (t, depth); 
			op = incOp;	
			break;
		}
		case 89: {
			Get();
			tsym (t, depth); 
			op = decOp;	
			break;
		}
		case 70: {
			Get();
			tsym (t, depth); 
			op = trueOp;	
			break;
		}
		case 29: {
			Get();
			tsym (t, depth); 
			op = falseOp;	
			break;
		}
		case 118: {
			Get();
			tsym (t, depth); 
			op = timesOp;	
			break;
		}
		case 139: {
			Get();
			tsym (t, depth); 
			op = divOp;	
			break;
		}
		case 140: {
			Get();
			tsym (t, depth); 
			op = modOp;	
			break;
		}
		case 83: {
			Get();
			tsym (t, depth); 
			op = andOp;	
			break;
		}
		case 137: {
			Get();
			tsym (t, depth); 
			op = orOp;	
			break;
		}
		case 138: {
			Get();
			tsym (t, depth); 
			op = xorOp;	
			break;
		}
		case 102: {
			Get();
			tsym (t, depth); 
			op = lshiftOp;
			break;
		}
		case 93: {
			Get();
			tsym (t, depth); 
			op = eqOp;	
			break;
		}
		case 106: {
			Get();
			tsym (t, depth); 
			op = neqOp;	
			break;
		}
		case 94: {
			Get();
			tsym (t, depth); 
			op = gtOp;	
			if (la.kind == 94) {
				if (la.pos > t.pos+1) Error ("no whitespace allowed in right shift operator"); 
				Get();
				tsym (t, depth); 
				op = rshiftOp;
			}
			break;
		}
		case 101: {
			Get();
			tsym (t, depth); 
			op = ltOp;	
			break;
		}
		case 95: {
			Get();
			tsym (t, depth); 
			op = gteOp;	
			break;
		}
		case 122: {
			Get();
			tsym (t, depth); 
			op = lteOp;	
			break;
		}
		default: SynErr(173); break;
		}
		lntsym (); --depth; 
	}

	void MemberName(out ASTMemberName memberName) {
		memberName = new ASTMemberName(); string identif = ""; ASTTypeArgumentList targs = null; 
		ntsym ("MemberName", depth); 
		++depth; 
		Expect(1);
		tsym (t, depth); 
		identif = t.val; 
		if (la.kind == 92) {
			Get();
			tsym (t, depth); 
			identif = "::"; 
			Expect(1);
			tsym (t, depth); 
			identif = t.val; 
		}
		if (la.kind == _lt && IsPartOfMemberName()) {
			TypeArgumentList(out targs);
		}
		memberName.parts.Add (new ASTTypeNamePart(identif, targs)); 
		while (la.kind == _dot && kindInContext(Peek(1).kind) == _ident) {
			Expect(91);
			tsym (t, depth); 
			Expect(1);
			tsym (t, depth); 
			identif = t.val; 
			if (la.kind == _lt && IsPartOfMemberName()) {
				TypeArgumentList(out targs);
			}
			memberName.parts.Add (new ASTTypeNamePart(identif, targs)); 
		}
		lntsym (); --depth; 
	}

	void AccessorDeclarations(Modifiers m, ASTAccessorNormals accessorDecls) {
		Modifiers	am		= new Modifiers (this);
		bool		getFound= false, setFound = false;
		                                  
		ntsym ("AccessorDeclarations", depth); 
		++depth; 
		ASTAttributeGroup	attrGroup	= null;
		ASTAttributeGroups	attrGroups	= null;
		ASTBlock			block		= null;
		ASTAccessorNormal	accessor1	= null, accessor2 = null;
		
		while (la.kind == 98) {
			if (null == attrGroups) attrGroups = new ASTAttributeGroups(); 
			Attributes(out attrGroup);
			attrGroups.Add ( attrGroup ); 
		}
		ModifierList(am);
		am.Check (accessorsPossib1Mod, accessorsPossib2Mod); 
		if (la.val.Equals ("get")) {
			Expect(1);
			tsym (t, depth); 
			getFound = true; accessor1 = new ASTAccessorNormalGet(); if (null != attrGroups) accessor1.attrGroups.AddRange(attrGroups); accessor1.modifiers = am.getModifiers(); 
		} else if (la.val.Equals ("set")) {
			Expect(1);
			tsym (t, depth); 
			setFound = true; accessor1 = new ASTAccessorNormalSet(); if (null != attrGroups) accessor1.attrGroups.AddRange(attrGroups); accessor1.modifiers = am.getModifiers(); 
		} else if (la.kind == 1) {
			Get();
			tsym (t, depth); 
			Error ("set or get expected"); 
		} else SynErr(174);
		if (la.kind == 97) {
			Block(out block);
			if (accessor1 != null) accessor1.block = block; 
		} else if (la.kind == 116) {
			Get();
			tsym (t, depth); 
		} else SynErr(175);
		if (accessor1 != null) accessorDecls.Add(accessor1); 
		if (StartOf(22)) {
			am = new Modifiers(this); attrGroups = null; 
			while (la.kind == 98) {
				if (null == attrGroups) attrGroups = new ASTAttributeGroups(); 
				Attributes(out attrGroup);
				attrGroups.Add ( attrGroup ); 
			}
			ModifierList(am);
			am.Check(accessorsPossib1Mod, accessorsPossib2Mod); 
			if (la.val.Equals("get")) {
				Expect(1);
				tsym (t, depth); 
				if (getFound) Error("get already declared");  getFound = true; 
				accessor2 = new ASTAccessorNormalGet (); if (null != attrGroups) accessor2.attrGroups.AddRange(attrGroups); accessor2.modifiers = am.getModifiers(); 
			} else if (la.val.Equals("set")) {
				Expect(1);
				tsym (t, depth); 
				if (setFound) Error("set already declared");  setFound = true; 
				accessor2 = new ASTAccessorNormalSet (); if (null != attrGroups) accessor2.attrGroups.AddRange(attrGroups); accessor2.modifiers = am.getModifiers(); 
			} else if (la.kind == 1) {
				Get();
				tsym (t, depth); 
				Error("set or get expected"); 
			} else SynErr(176);
			if (la.kind == 97) {
				Block(out block);
				if (accessor2 != null) accessor2.block = block; 
			} else if (la.kind == 116) {
				Get();
				tsym (t, depth); 
			} else SynErr(177);
			if (accessor2 != null) accessorDecls.Add(accessor2); 
		}
		lntsym (); --depth; 
	}

	void InterfaceAccessors(Modifiers m, ASTAccessorInterfaces accessorDecls) {
		bool getFound = false, setFound = false; 
		ntsym ("InterfaceAccessors", depth); 
		++depth; 
		ASTAttributeGroup		attrGroup	= null;
		ASTAttributeGroups		attrGroups	= null;
		ASTAccessorInterface	accessor1	= null, accessor2 = null;
		
		while (la.kind == 98) {
			if (null == attrGroups) attrGroups = new ASTAttributeGroups(); 
			Attributes(out attrGroup);
			attrGroups.Add ( attrGroup ); 
		}
		if (la.val.Equals("get")) {
			Expect(1);
			tsym (t, depth); 
			getFound = true;  accessor1 = new ASTAccessorInterfaceGet (); if (null != attrGroups) accessor1.attrGroups.AddRange (attrGroups); 
		} else if (la.val.Equals("set")) {
			Expect(1);
			tsym (t, depth); 
			setFound = true;  accessor1 = new ASTAccessorInterfaceSet (); if (null != attrGroups) accessor1.attrGroups.AddRange (attrGroups); 
		} else if (la.kind == 1) {
			Get();
			tsym (t, depth); 
			Error("set or get expected"); 
		} else SynErr(178);
		Expect(116);
		tsym (t, depth); 
		if (accessor1 != null) accessorDecls.Add (accessor1); 
		if (la.kind == 1 || la.kind == 98) {
			attrGroups = null; 
			while (la.kind == 98) {
				if (null == attrGroups) attrGroups = new ASTAttributeGroups(); 
				Attributes(out attrGroup);
				attrGroups.Add ( attrGroup ); 
			}
			if (la.val.Equals("get")) {
				Expect(1);
				tsym (t, depth); 
				if (getFound) Error("get already declared"); accessor2 = new ASTAccessorInterfaceGet (); if (null != attrGroups) accessor2.attrGroups.AddRange (attrGroups); 
			} else if (la.val.Equals("set")) {
				Expect(1);
				tsym (t, depth); 
				if (setFound) Error("set already declared"); accessor2 = new ASTAccessorInterfaceSet (); if (null != attrGroups) accessor2.attrGroups.AddRange (attrGroups); 
			} else if (la.kind == 1) {
				Get();
				tsym (t, depth); 
				Error("set or get expected");				
			} else SynErr(179);
			Expect(116);
			tsym (t, depth); 
		}
		if (accessor2 != null) accessorDecls.Add (accessor2); 
		lntsym (); --depth; 
	}

	void LocalVariableType(out ASTType ty) {
		ntsym ("LocalVariableType", depth); 
		++depth; 
		ty = null; 
		TypeKind dummy; 
		Type(out dummy, false, out ty);
		lntsym (); --depth; 
	}

	void LocalVariableDeclaration(out ASTLocalVarDeclton localVarDeclton) {
		ntsym ("LocalVariableDeclaration", depth); 
		++depth; 
		ASTType ty; ASTLocalVarDecltor localVarDecltor; 
		localVarDeclton = new ASTLocalVarDeclton(); 
		LocalVariableType(out ty);
		localVarDeclton.type = ty; 
		LocalVariableDeclarator(out localVarDecltor);
		localVarDeclton.localVarDecltors.Add(localVarDecltor); 
		while (la.kind == 88) {
			Get();
			tsym (t, depth); 
			LocalVariableDeclarator(out localVarDecltor);
			localVarDeclton.localVarDecltors.Add(localVarDecltor); 
		}
		lntsym (); --depth; 
	}

	void LocalVariableDeclarator(out ASTLocalVarDecltor localVarDecltor) {
		TypeKind	dummy; 
		ntsym ("LocalVariableDeclarator", depth); 
		++depth; 
		localVarDecltor = null; 
		Expect(1);
		tsym (t, depth); 
		string sIdent = t.val; 
		if (la.kind == 88 || la.kind == 115 || la.kind == 116) {
			localVarDecltor = new ASTLocalVarDecltorNormal(); localVarDecltor.ident = sIdent; 
		} else if (la.kind == 86) {
			Get();
			tsym (t, depth); 
			if (StartOf(23)) {
				ASTVariableInitializer varInitializer; 
				VariableInitializer(out varInitializer);
				localVarDecltor = new ASTLocalVarDecltorNormal(); localVarDecltor.ident = sIdent; 
				((ASTLocalVarDecltorNormal)localVarDecltor).varInitializer = varInitializer; 
			} else if (la.kind == 63) {
				Get();
				tsym (t, depth); 
				localVarDecltor = new ASTLocalVarDecltorStackalloc(); localVarDecltor.ident = sIdent; 
				ASTType ty; 
				Type(out dummy, false, out ty);
				((ASTLocalVarDecltorStackalloc)localVarDecltor).type = ty; 
				Expect(98);
				tsym (t, depth); 
				ASTExpr expr; 
				Expression(out expr);
				((ASTLocalVarDecltorStackalloc)localVarDecltor).expression = expr; 
				Expect(114);
				tsym (t, depth); 
			} else SynErr(180);
		} else SynErr(181);
		lntsym (); --depth; 
	}

	void VariableInitializer(out ASTVariableInitializer varInitializer) {
		ntsym ("VariableInitializer", depth); 
		++depth; 
		ASTExpr expr ; varInitializer = null; 
		if (StartOf(19)) {
			Expression(out expr);
			varInitializer = new ASTVariableInitializerExpr (expr); 
		} else if (la.kind == 97) {
			ArrayInitializer();
			varInitializer = new ASTVariableInitializerArray (); 
		} else SynErr(182);
		lntsym (); --depth; 
	}

	void ArrayInitializer() {
		ntsym ("ArrayInitializer", depth); 
		++depth; 
		ASTVariableInitializer varInitializer; 
		Expect(97);
		tsym (t, depth); 
		if (StartOf(23)) {
			VariableInitializer(out varInitializer);
			while (NotFinalComma()) {
				Expect(88);
				tsym (t, depth); 
				VariableInitializer(out varInitializer);
			}
			if (la.kind == 88) {
				Get();
				tsym (t, depth); 
			}
		}
		Expect(113);
		tsym (t, depth); 
		lntsym (); --depth; 
	}

	void Attribute(out ASTAttribute attribute) {
		ASTTypeName typeName; 
		ntsym ("Attribute", depth); 
		++depth; 
		attribute		= new ASTAttribute(); 
		TypeName(out typeName);
		attribute.name	= typeName; 
		if (la.kind == 99) {
			AttributeArguments(attribute.arguments);
		}
		lntsym (); --depth; 
	}

	void Keyword() {
		ntsym ("Keyword", depth); 
		++depth; 
		switch (la.kind) {
		case 6: {
			Get();
			break;
		}
		case 7: {
			Get();
			break;
		}
		case 8: {
			Get();
			break;
		}
		case 9: {
			Get();
			break;
		}
		case 10: {
			Get();
			break;
		}
		case 11: {
			Get();
			break;
		}
		case 12: {
			Get();
			break;
		}
		case 13: {
			Get();
			break;
		}
		case 14: {
			Get();
			break;
		}
		case 15: {
			Get();
			break;
		}
		case 16: {
			Get();
			break;
		}
		case 17: {
			Get();
			break;
		}
		case 18: {
			Get();
			break;
		}
		case 19: {
			Get();
			break;
		}
		case 20: {
			Get();
			break;
		}
		case 21: {
			Get();
			break;
		}
		case 22: {
			Get();
			break;
		}
		case 23: {
			Get();
			break;
		}
		case 24: {
			Get();
			break;
		}
		case 25: {
			Get();
			break;
		}
		case 26: {
			Get();
			break;
		}
		case 27: {
			Get();
			break;
		}
		case 28: {
			Get();
			break;
		}
		case 29: {
			Get();
			break;
		}
		case 30: {
			Get();
			break;
		}
		case 31: {
			Get();
			break;
		}
		case 32: {
			Get();
			break;
		}
		case 33: {
			Get();
			break;
		}
		case 34: {
			Get();
			break;
		}
		case 35: {
			Get();
			break;
		}
		case 36: {
			Get();
			break;
		}
		case 37: {
			Get();
			break;
		}
		case 38: {
			Get();
			break;
		}
		case 39: {
			Get();
			break;
		}
		case 40: {
			Get();
			break;
		}
		case 41: {
			Get();
			break;
		}
		case 42: {
			Get();
			break;
		}
		case 43: {
			Get();
			break;
		}
		case 44: {
			Get();
			break;
		}
		case 45: {
			Get();
			break;
		}
		case 46: {
			Get();
			break;
		}
		case 47: {
			Get();
			break;
		}
		case 48: {
			Get();
			break;
		}
		case 49: {
			Get();
			break;
		}
		case 50: {
			Get();
			break;
		}
		case 51: {
			Get();
			break;
		}
		case 52: {
			Get();
			break;
		}
		case 53: {
			Get();
			break;
		}
		case 54: {
			Get();
			break;
		}
		case 55: {
			Get();
			break;
		}
		case 56: {
			Get();
			break;
		}
		case 57: {
			Get();
			break;
		}
		case 58: {
			Get();
			break;
		}
		case 59: {
			Get();
			break;
		}
		case 60: {
			Get();
			break;
		}
		case 61: {
			Get();
			break;
		}
		case 62: {
			Get();
			break;
		}
		case 63: {
			Get();
			break;
		}
		case 64: {
			Get();
			break;
		}
		case 65: {
			Get();
			break;
		}
		case 66: {
			Get();
			break;
		}
		case 67: {
			Get();
			break;
		}
		case 68: {
			Get();
			break;
		}
		case 69: {
			Get();
			break;
		}
		case 70: {
			Get();
			break;
		}
		case 71: {
			Get();
			break;
		}
		case 72: {
			Get();
			break;
		}
		case 73: {
			Get();
			break;
		}
		case 74: {
			Get();
			break;
		}
		case 75: {
			Get();
			break;
		}
		case 76: {
			Get();
			break;
		}
		case 77: {
			Get();
			break;
		}
		case 78: {
			Get();
			break;
		}
		case 79: {
			Get();
			break;
		}
		case 80: {
			Get();
			break;
		}
		case 81: {
			Get();
			break;
		}
		case 82: {
			Get();
			break;
		}
		default: SynErr(183); break;
		}
		tsym (t, depth); 
		lntsym (); --depth; 
	}

	void AttributeArguments(ASTAttributeArguments arguments) {
		bool nameFound = false; 
		ntsym ("AttributeArguments", depth); 
		++depth; 
		ASTExpr expr;  ASTAttributeArgument argument; 
		Expect(99);
		tsym (t, depth); 
		if (StartOf(19)) {
			argument = new ASTAttributeArgument(); 
			if (IsAssignment()) {
				nameFound = true;
				Expect(1);
				tsym (t, depth); 
				argument.ident = t.val; 
				Expect(86);
				tsym (t, depth); 
			}
			Expression(out expr);
			argument.expression = expr; arguments.Add (argument); 
			while (la.kind == 88) {
				argument = new ASTAttributeArgument(); 
				Get();
				tsym (t, depth); 
				if (IsAssignment()) {
					nameFound = true;
					Expect(1);
					tsym (t, depth); 
					argument.ident = t.val; 
					Expect(86);
					tsym (t, depth); 
				} else if (StartOf(19)) {
					if (nameFound) Error("no positional argument after named arguments"); 
				} else SynErr(184);
				Expression(out expr);
				argument.expression = expr; arguments.Add (argument); 
			}
		}
		Expect(115);
		tsym (t, depth); 
		lntsym (); --depth; 
	}

	void PrimitiveType(out ASTTypeName typeName) {
		ntsym ("PrimitiveType", depth); 
		++depth; 
		typeName = null; 
		if (StartOf(24)) {
			IntegralType(out typeName);
		} else if (la.kind == 32) {
			Get();
			tsym (t, depth); 
			typeName = new ASTTypeName(t.val); 
		} else if (la.kind == 23) {
			Get();
			tsym (t, depth); 
			typeName = new ASTTypeName(t.val); 
		} else if (la.kind == 19) {
			Get();
			tsym (t, depth); 
			typeName = new ASTTypeName(t.val); 
		} else if (la.kind == 9) {
			Get();
			tsym (t, depth); 
			typeName = new ASTTypeName(t.val); 
		} else SynErr(185);
		lntsym (); --depth; 
	}

	void PointerOrArray(out TypeKind type, TypeKind curType, ASTType ty) {
		type = curType; int dims = 0; 
		ntsym ("PointerOrArray", depth); 
		++depth; 
		while (IsPointerOrDims()) {
			if (la.kind == 118) {
				ty.isPointer	= true;	
				Get();
				tsym (t, depth);		
				type = TypeKind.pointer; ty.textPtrOrArray += t.val; 
			} else if (la.kind == 98) {
				ty.isArray	= true;	
				Get();
				tsym (t, depth);		
				dims = 1; type = TypeKind.array; 
				ty.dimensions = 1; ty.textPtrOrArray += t.val; 
				while (la.kind == 88) {
					Get();
					tsym (t, depth);		
					dims++; 
					ty.dimensions++; ty.textPtrOrArray += t.val; 
				}
				Expect(114);
				tsym (t, depth);		
				ty.textPtrOrArray += t.val; 
			} else SynErr(186);
		}
		lntsym (); --depth;	
	}

	void ResolvedType(out ASTResolvedType rs) {
		TypeKind					type	= TypeKind.simple;
		ASTType						ty		= new ASTType();
		ASTTypeName					typeName= null;
		ASTTypeArgumentList			targs	= null;
		string						identif	= "";
		
		ntsym ("ResolvedType", depth);	
		++depth; 
		rs = new ASTResolvedType ();		
		if (StartOf(11)) {
			PrimitiveType(out typeName);
			rs.typeKind = ASTTypeKind.Primitive; rs.typeName = typeName;	
		} else if (la.kind == 48) {
			Get();
			tsym (t, depth); 
			rs.typeKind = ASTTypeKind.Class; rs.typeName = new ASTTypeName("object"); 
		} else if (la.kind == 65) {
			Get();
			tsym (t, depth); 
			rs.typeKind = ASTTypeKind.Class; rs.typeName = new ASTTypeName("string"); 
		} else if (la.kind == 1) {
			Get();
			tsym (t, depth); 
			rs.typeKind = ASTTypeKind.Class; rs.typeName = new ASTTypeName(); identif = t.val; 
			if (la.kind == 92) {
				Get();
				tsym (t, depth); 
				identif += "::";		
				Expect(1);
				tsym (t, depth); 
				identif += t.val;	
			}
			if (IsGeneric()) {
				TypeArgumentList(out targs);
			}
			rs.typeName.parts.Add (new ASTTypeNamePart(identif, targs)); 
			while (la.kind == 91) {
				Get();
				tsym (t, depth); 
				Expect(1);
				tsym (t, depth); 
				identif = t.val; 
				if (IsGeneric()) {
					TypeArgumentList(out targs);
				}
				rs.typeName.parts.Add (new ASTTypeNamePart(identif, targs)); 
			}
		} else if (la.kind == 80) {
			Get();
			tsym (t, depth); 
			type = TypeKind.@void; 
			rs.typeKind = ASTTypeKind.Void; rs.typeName = new ASTTypeName("void");  
		} else SynErr(187);
		if (la.kind == _question && ! firstExpr[kindInContext(Peek(1).kind)]) {
			Expect(112);
			tsym (t, depth); 
			if (type == TypeKind.@void) { Error("Unexpected token ?, void must not be nullable."); } 
			rs.isNullable = true; 
		}
		PointerOrArray(out type, type, ty);
		if (type == TypeKind.@void) Error("type expected, void found, maybe you mean void*"); 
		rs.dimensions	= ty.dimensions;
		rs.isArray		= ty.isArray;
		rs.isPointer	= ty.isPointer;
		rs.textPtrOrArray= ty.textPtrOrArray;	
		lntsym (); --depth; 
	}

	void TypeArgumentList(out ASTTypeArgumentList targs) {
		TypeKind dummy;
		targs = new ASTTypeArgumentList();
		ASTType ty;
		
		ntsym ("TypeArgumentList", depth); 
		++depth; 
		Expect(101);
		tsym (t, depth); 
		if (StartOf(16)) {
			Type(out dummy, false, out ty);
			targs.Add (ty); 
		} else if (la.kind == 88 || la.kind == 94) {
		} else SynErr(188);
		while (la.kind == 88) {
			Get();
			tsym (t, depth); 
			if (StartOf(16)) {
				Type(out dummy, false, out ty);
				targs.Add (ty); 
			} else if (la.kind == 88 || la.kind == 94) {
			} else SynErr(189);
		}
		Expect(94);
		tsym (t, depth); 
		lntsym (); --depth; 
	}

	void InternalClassType(out ASTTypeName typeName) {
		ntsym ("InternalClassType", depth); 
		++depth; 
		typeName = null; 
		if (la.kind == 48) {
			Get();
			typeName = new ASTTypeName("object"); 
		} else if (la.kind == 65) {
			Get();
			typeName = new ASTTypeName("string"); 
		} else SynErr(190);
		tsym (t, depth); 
		lntsym (); --depth; 
	}

	void Statement(out ASTStatement stmt) {
		TypeKind		dummy;
		ASTType			ty;
		ASTExpr	expr;
		ASTStatement	stmtx;
		stmt = null;
		
		ntsym ("Statement", depth); 
		++depth; 
		if (kindInContext(la.kind) == _ident && Peek(1).kind == _colon) {
			stmt = new ASTStmtGotoLabel(); 
			Expect(1);
			tsym (t, depth); 
			((ASTStmtGotoLabel)stmt).ident = t.val; 
			Expect(87);
			tsym (t, depth); 
			Statement(out stmtx);
			((ASTStmtGotoLabel)stmt).statement = stmtx; 
		} else if (la.kind == 17) {
			Get();
			tsym (t, depth); 
			stmt = new ASTStmtLocalConst(); 
			Type(out dummy, false, out ty);
			((ASTStmtLocalConst)stmt).type = ty; 
			Expect(1);
			tsym (t, depth); 
			string sIdent = t.val; 
			Expect(86);
			tsym (t, depth); 
			Expression(out expr);
			((ASTStmtLocalConst)stmt).identExprPairs.Add (new ASTIdentExprPair(sIdent, expr)); 
			while (la.kind == 88) {
				Get();
				tsym (t, depth); 
				Expect(1);
				tsym (t, depth); 
				sIdent = t.val; 
				Expect(86);
				tsym (t, depth); 
				Expression(out expr);
				((ASTStmtLocalConst)stmt).identExprPairs.Add (new ASTIdentExprPair(sIdent, expr)); 
			}
			Expect(116);
			tsym (t, depth); 
		} else if (la.kind == _void || IsLocalVarDecl()) {
			stmt = new ASTStmtLocalVar(); 
			ASTLocalVarDeclton localVarDeclton; 
			LocalVariableDeclaration(out localVarDeclton);
			((ASTStmtLocalVar)stmt).localVarDeclton = localVarDeclton; 
			Expect(116);
			tsym (t, depth); 
		} else if (StartOf(25)) {
			EmbeddedStatement(out stmt);
		} else SynErr(191);
		lntsym (); --depth; 
	}

	void EmbeddedStatement(out ASTStatement stmt) {
		TypeKind		type;
		ASTType			ty;
		ASTExpr	expr  = null;
		ASTBlock		block = null;
		ASTStatement	stmtx = null;
		stmt = null;
		
		ntsym ("EmbeddedStatement", depth); 
		++depth; 
		if (la.kind == 97) {
			Block(out block);
			stmt = new ASTEmbStmtBlock ();			
			((ASTEmbStmtBlock)stmt).block = block;	
		} else if (la.kind == 116) {
			Get();
			tsym (t, depth); 
			stmt = new ASTEmbStmtSemicolon ();		
		} else if (la.kind == _checked && Peek(1).kind == _lbrace) {
			Expect(15);
			tsym (t, depth); 
			stmt = new ASTEmbStmtChecked();			
			Block(out block);
			((ASTEmbStmtChecked)stmt).block = block; 
		} else if (la.kind == _unchecked && Peek(1).kind == _lbrace) {
			Expect(75);
			tsym (t, depth); 
			stmt = new ASTEmbStmtUnchecked();		
			Block(out block);
			((ASTEmbStmtUnchecked)stmt).block = block; 
		} else if (IsYieldReturn()) {
			stmt = new ASTEmbStmtYield (); 
			Expect(1);
			tsym (t, depth); 
			if (la.kind == 58) {
				Get();
				tsym (t, depth); 
				Expression(out expr);
				((ASTEmbStmtYield)stmt).expression = expr; 
			} else if (la.kind == 10) {
				Get();
				tsym (t, depth); 
			} else SynErr(192);
			Expect(116);
			tsym (t, depth); 
		} else if (StartOf(20)) {
			ASTStatementExpression statexp; 
			StatementExpression(out statexp);
			stmt = new ASTEmbStmtStatementExpression(); 
			((ASTEmbStmtStatementExpression)stmt).stmtExpr = statexp; 
			Expect(116);
			tsym (t, depth); 
		} else if (la.kind == 36) {
			Get();
			tsym (t, depth); 
			stmt = new ASTEmbStmtIf (); 
			Expect(99);
			tsym (t, depth); 
			Expression(out expr);
			((ASTEmbStmtIf)stmt).testExpression	= expr;	
			Expect(115);
			tsym (t, depth); 
			EmbeddedStatement(out stmtx);
			((ASTEmbStmtIf)stmt).thenStatement	= stmtx;
			if (la.kind == 24) {
				Get();
				tsym (t, depth); 
				EmbeddedStatement(out stmtx);
				((ASTEmbStmtIf)stmt).elseStatement	= stmtx;
			}
		} else if (la.kind == 67) {
			Get();
			tsym (t, depth); 
			stmt = new ASTEmbStmtSwitch(); 
			Expect(99);
			tsym (t, depth); 
			Expression(out expr);
			((ASTEmbStmtSwitch)stmt).expression	= expr;	
			Expect(115);
			tsym (t, depth); 
			Expect(97);
			tsym (t, depth); 
			while (la.kind == 12 || la.kind == 20) {
				ASTSwitchSection switchSection; 
				SwitchSection(out switchSection);
				((ASTEmbStmtSwitch)stmt).switchSections.Add (switchSection); 
			}
			Expect(113);
			tsym (t, depth); 
		} else if (la.kind == 82) {
			Get();
			tsym (t, depth); 
			stmt = new ASTEmbStmtWhile(); 
			Expect(99);
			tsym (t, depth); 
			Expression(out expr);
			((ASTEmbStmtWhile)stmt).expression	= expr; 
			Expect(115);
			tsym (t, depth); 
			EmbeddedStatement(out stmtx);
			((ASTEmbStmtWhile)stmt).statement	= stmtx; 
		} else if (la.kind == 22) {
			Get();
			tsym (t, depth); 
			stmt = new ASTEmbStmtDo(); 
			EmbeddedStatement(out stmtx);
			((ASTEmbStmtDo)stmt).statement	= stmtx; 
			Expect(82);
			tsym (t, depth); 
			Expect(99);
			tsym (t, depth); 
			Expression(out expr);
			((ASTEmbStmtDo)stmt).expression	= expr; 
			Expect(115);
			tsym (t, depth); 
			Expect(116);
			tsym (t, depth); 
		} else if (la.kind == 33) {
			Get();
			tsym (t, depth); 
			stmt = new ASTEmbStmtFor(); 
			Expect(99);
			tsym (t, depth); 
			if (StartOf(26)) {
				ASTForInitializer forInit; 
				ForInitializer(out forInit);
				((ASTEmbStmtFor)stmt).forInit = forInit; 
			}
			Expect(116);
			tsym (t, depth); 
			if (StartOf(19)) {
				Expression(out expr);
				((ASTEmbStmtFor)stmt).expression		= expr;	
			}
			Expect(116);
			tsym (t, depth); 
			if (StartOf(20)) {
				ASTForIterator forIter; 
				ForIterator(out forIter);
				((ASTEmbStmtFor)stmt).forIter		= forIter; 
			}
			Expect(115);
			tsym (t, depth); 
			EmbeddedStatement(out stmtx);
			((ASTEmbStmtFor)stmt).statement		= stmtx;
		} else if (la.kind == 34) {
			Get();
			tsym (t, depth); 
			stmt = new ASTEmbStmtForeach(); 
			Expect(99);
			tsym (t, depth); 
			ASTType typeAux; 
			LocalVariableType(out typeAux);
			((ASTEmbStmtForeach)stmt).type		= typeAux; 
			Expect(1);
			tsym (t, depth); 
			((ASTEmbStmtForeach)stmt).ident		= t.val;
			Expect(38);
			tsym (t, depth); 
			Expression(out expr);
			((ASTEmbStmtForeach)stmt).expression	= expr;	
			Expect(115);
			tsym (t, depth); 
			EmbeddedStatement(out stmtx);
			((ASTEmbStmtForeach)stmt).statement	= stmtx;
		} else if (la.kind == 10) {
			Get();
			tsym (t, depth); 
			stmt = new ASTEmbStmtBreak();			
			Expect(116);
			tsym (t, depth); 
		} else if (la.kind == 18) {
			Get();
			tsym (t, depth); 
			stmt = new ASTEmbStmtContinue();			
			Expect(116);
			tsym (t, depth); 
		} else if (la.kind == 35) {
			Get();
			tsym (t, depth); 
			stmt = new ASTEmbStmtGoto();				
			if (la.kind == 1) {
				Get();
				tsym (t, depth); 
				((ASTEmbStmtGoto)stmt).ident = t.val;	
			} else if (la.kind == 12) {
				Get();
				tsym (t, depth); 
				Expression(out expr);
				((ASTEmbStmtGoto)stmt).expression = expr;
			} else if (la.kind == 20) {
				Get();
				tsym (t, depth); 
			} else SynErr(193);
			Expect(116);
			tsym (t, depth); 
		} else if (la.kind == 58) {
			Get();
			tsym (t, depth); 
			stmt = new ASTEmbStmtReturn (); 
			if (StartOf(19)) {
				Expression(out expr);
				((ASTEmbStmtReturn)stmt).expression = expr; 
			}
			Expect(116);
			tsym (t, depth); 
		} else if (la.kind == 69) {
			Get();
			tsym (t, depth); 
			stmt = new ASTEmbStmtThrow (); 
			if (StartOf(19)) {
				Expression(out expr);
				((ASTEmbStmtThrow )stmt).expression = expr; 
			}
			Expect(116);
			tsym (t, depth); 
		} else if (la.kind == 71) {
			Get();
			tsym (t, depth); 
			stmt = new ASTEmbStmtTry(); 
			Block(out block);
			((ASTEmbStmtTry)stmt).tryBlock = block; 
			if (la.kind == 13) {
				CatchClauses(((ASTEmbStmtTry)stmt).catchs);
				if (la.kind == 30) {
					Get();
					tsym (t, depth); 
					Block(out block);
					((ASTEmbStmtTry)stmt).finallyBlock = block; 
				}
			} else if (la.kind == 30) {
				Get();
				tsym (t, depth); 
				Block(out block);
				((ASTEmbStmtTry)stmt).finallyBlock = block; 
			} else SynErr(194);
		} else if (la.kind == 43) {
			Get();
			tsym (t, depth); 
			stmt = new ASTEmbStmtLock(); 
			Expect(99);
			tsym (t, depth); 
			Expression(out expr);
			((ASTEmbStmtLock)stmt).expression = expr; 
			Expect(115);
			tsym (t, depth); 
			EmbeddedStatement(out stmtx);
			((ASTEmbStmtLock)stmt).statement = stmtx; 
		} else if (la.kind == 78) {
			Get();
			tsym (t, depth); 
			stmt = new ASTEmbStmtUsing(); 
			Expect(99);
			tsym (t, depth); 
			ASTResourceAcquisition resourceAc; 
			ResourceAcquisition(out resourceAc);
			((ASTEmbStmtUsing)stmt).resourceAc = resourceAc; 
			Expect(115);
			tsym (t, depth); 
			EmbeddedStatement(out stmtx);
			((ASTEmbStmtUsing)stmt).statement= stmtx; 
		} else if (la.kind == 76) {
			Get();
			tsym (t, depth); 
			stmt = new ASTEmbStmtUnsafe(); 
			Block(out block);
			((ASTEmbStmtUnsafe)stmt).block = block; 
		} else if (la.kind == 31) {
			Get();
			tsym (t, depth); 
			stmt = new ASTEmbStmtFixed(); 
			Expect(99);
			tsym (t, depth); 
			Type(out type, false, out ty);
			if (type == TypeKind.pointer) ((ASTEmbStmtFixed)stmt).type = ty; else Error("can only fix pointer types"); 
			Expect(1);
			tsym (t, depth); 
			string sIdent = t.val; 
			Expect(86);
			tsym (t, depth); 
			Expression(out expr);
			((ASTEmbStmtFixed)stmt).identExprPairs.Add (new ASTIdentExprPair(sIdent, expr)); 
			while (la.kind == 88) {
				Get();
				tsym (t, depth); 
				Expect(1);
				tsym (t, depth); 
				sIdent = t.val; 
				Expect(86);
				tsym (t, depth); 
				Expression(out expr);
				((ASTEmbStmtFixed)stmt).identExprPairs.Add (new ASTIdentExprPair(sIdent, expr)); 
			}
			Expect(115);
			tsym (t, depth); 
			EmbeddedStatement(out stmtx);
			((ASTEmbStmtFixed)stmt).statement = stmtx; 
		} else SynErr(195);
		lntsym (); --depth; 
	}

	void StatementExpression(out ASTStatementExpression statexp) {
		bool isAssignment = assnStartOp[kindInContext(la.kind)] || IsTypeCast(); 
		ntsym ("StatementExpression", depth); 
		++depth; 
		statexp = new ASTStatementExpression(); ASTExpr expr ; ASTExprUnary exprUnary ;  
		Unary(out exprUnary);
		statexp.unary= exprUnary;
		if (StartOf(27)) {
			string sop	= "";	
			AssignmentOperator(out sop);
			statexp.sop	= sop;	
			Expression(out expr);
			statexp.expr	= expr;	
		} else if (la.kind == 88 || la.kind == 115 || la.kind == 116) {
			if (isAssignment) Error("error in assignment."); 
		} else SynErr(196);
		lntsym (); --depth; 
	}

	void SwitchSection(out ASTSwitchSection switchSection) {
		ntsym ("SwitchSection", depth); 
		++depth; 
		ASTStatement		stmt;		
		ASTSwitchLabel	switchLabel;
		switchSection = new ASTSwitchSection(); 
		SwitchLabel(out switchLabel);
		switchSection.switchLabels.Add (switchLabel); 
		while (la.kind == _case || (la.kind == _default && Peek(1).kind == _colon)) {
			SwitchLabel(out switchLabel);
			switchSection.switchLabels.Add (switchLabel); 
		}
		Statement(out stmt);
		switchSection.statements.Add (stmt); 
		while (IsNoSwitchLabelOrRBrace()) {
			Statement(out stmt);
			switchSection.statements.Add (stmt); 
		}
		lntsym (); --depth; 
	}

	void ForInitializer(out ASTForInitializer forInit) {
		ntsym ("ForInitializer", depth);   
		++depth; 
		forInit = new ASTForInitializer(); 
		if (IsLocalVarDecl()) {
			ASTLocalVarDeclton localVarDeclton;			
			LocalVariableDeclaration(out localVarDeclton);
			forInit.localVarDeclton = localVarDeclton;	
		} else if (StartOf(20)) {
			ASTStatementExpression statexp; 
			StatementExpression(out statexp);
			forInit.stmtsExprs.Add(statexp); 
			while (la.kind == 88) {
				Get();
				tsym (t, depth); 
				StatementExpression(out statexp);
				forInit.stmtsExprs.Add(statexp); 
			}
		} else SynErr(197);
		lntsym (); --depth; 
	}

	void ForIterator(out ASTForIterator forIter) {
		ntsym ("ForIterator", depth); 
		++depth; 
		forIter = new ASTForIterator(); 
		ASTStatementExpression statexp; 
		StatementExpression(out statexp);
		forIter.stmtsExprs.Add (statexp); 
		while (la.kind == 88) {
			Get();
			tsym (t, depth); 
			StatementExpression(out statexp);
			forIter.stmtsExprs.Add (statexp); 
		}
		lntsym (); --depth; 
	}

	void CatchClauses(ASTCatchs catchs) {
		ASTTypeName typeName; ASTBlock block; 
		ntsym ("CatchClauses", depth); 
		++depth; 
		ASTCatch catchx = new ASTCatch(); 
		Expect(13);
		tsym (t, depth); 
		if (la.kind == 97) {
			Block(out block);
			catchx.block = block; 
			catchs.Add (catchx); 
		} else if (la.kind == 99) {
			Get();
			tsym (t, depth); 
			ClassType(out typeName);
			catchx.typeName = typeName; 
			if (la.kind == 1) {
				Get();
				tsym (t, depth); 
				catchx.ident = t.val; 
			}
			Expect(115);
			tsym (t, depth); 
			Block(out block);
			catchx.block = block; 
			catchs.Add (catchx); 
			if (la.kind == 13) {
				CatchClauses(catchs);
			}
		} else SynErr(198);
		lntsym (); --depth; 
	}

	void ResourceAcquisition(out ASTResourceAcquisition resourceAc) {
		ntsym ("ResourceAcquisition", depth); 
		++depth; 
		resourceAc = null; 
		if (IsLocalVarDecl()) {
			resourceAc = new ASTResourceAcquisitionVarDeclton(); ASTLocalVarDeclton	localVarDeclton; 
			LocalVariableDeclaration(out localVarDeclton);
			((ASTResourceAcquisitionVarDeclton)resourceAc).localVarDeclton	= localVarDeclton; 
		} else if (StartOf(19)) {
			resourceAc = new ASTResourceAcquisitionExpression(); ASTExpr expr; 
			Expression(out expr);
			((ASTResourceAcquisitionExpression)resourceAc).expression		= expr; 
		} else SynErr(199);
		lntsym (); --depth; 
	}

	void Unary(out ASTExprUnary exprUnary) {
		ntsym ("Unary", depth); 
		++depth; 
		TypeKind	dummy;
		ASTType		ty ;
		exprUnary = new ASTExprUnary();
		
		while (unaryHead[la.kind] || IsTypeCast()) {
			switch (la.kind) {
			case 110: {
				Get();
				tsym (t, depth); 
				exprUnary.unaryHead = new ASTExprUnaryHead(ASTExprUnaryHeadType.PLUS);		
				break;
			}
			case 103: {
				Get();
				tsym (t, depth); 
				exprUnary.unaryHead = new ASTExprUnaryHead(ASTExprUnaryHeadType.MINUS);		
				break;
			}
			case 107: {
				Get();
				tsym (t, depth); 
				exprUnary.unaryHead = new ASTExprUnaryHead(ASTExprUnaryHeadType.BOOLNOT);	
				break;
			}
			case 117: {
				Get();
				tsym (t, depth); 
				exprUnary.unaryHead = new ASTExprUnaryHead(ASTExprUnaryHeadType.BITNOT);		
				break;
			}
			case 96: {
				Get();
				tsym (t, depth); 
				exprUnary.unaryHead = new ASTExprUnaryHead(ASTExprUnaryHeadType.PLUSPLUS);	
				break;
			}
			case 89: {
				Get();
				tsym (t, depth); 
				exprUnary.unaryHead = new ASTExprUnaryHead(ASTExprUnaryHeadType.MINUSMINUS);	
				break;
			}
			case 118: {
				Get();
				tsym (t, depth); 
				exprUnary.unaryHead = new ASTExprUnaryHead(ASTExprUnaryHeadType.TIMES);		
				break;
			}
			case 83: {
				Get();
				tsym (t, depth); 
				exprUnary.unaryHead = new ASTExprUnaryHead(ASTExprUnaryHeadType.BITAND);		
				break;
			}
			case 99: {
				Get();
				tsym (t, depth); 
				Type(out dummy, false, out ty);
				exprUnary.unaryHead = new ASTExprUnaryHead(ASTExprUnaryHeadType.CAST, ty);	
				Expect(115);
				tsym (t, depth); 
				break;
			}
			default: SynErr(200); break;
			}
		}
		ASTExprPrim primary; 
		Primary(out primary);
		exprUnary.primary = primary; 
		lntsym (); --depth; 
	}

	void AssignmentOperator(out string sop) {
		ntsym ("AssignmentOperator", depth); 
		++depth; 
		sop = ""; 
		switch (la.kind) {
		case 86: {
			Get();
			tsym (t, depth); 
			sop = "="; 
			break;
		}
		case 111: {
			Get();
			tsym (t, depth); 
			sop = "+="; 
			break;
		}
		case 104: {
			Get();
			tsym (t, depth); 
			sop = "-="; 
			break;
		}
		case 119: {
			Get();
			tsym (t, depth); 
			sop = "*="; 
			break;
		}
		case 90: {
			Get();
			tsym (t, depth); 
			sop = "/="; 
			break;
		}
		case 105: {
			Get();
			tsym (t, depth); 
			sop = "%="; 
			break;
		}
		case 84: {
			Get();
			tsym (t, depth); 
			sop = "&="; 
			break;
		}
		case 109: {
			Get();
			tsym (t, depth); 
			sop = "|="; 
			break;
		}
		case 120: {
			Get();
			tsym (t, depth); 
			sop = "^="; 
			break;
		}
		case 100: {
			Get();
			tsym (t, depth); 
			sop = "<<="; 
			break;
		}
		case 94: {
			Get();
			tsym (t, depth); 
			int pos = t.pos; 
			Expect(95);
			tsym (t, depth); 
			if (pos+1 < t.pos) Error("no whitespace allowed in right shift assignment"); 
			sop = ">>="; 
			break;
		}
		default: SynErr(201); break;
		}
		lntsym (); --depth; 
	}

	void SwitchLabel(out ASTSwitchLabel switchLabel) {
		ntsym ("SwitchLabel", depth); 
		++depth; 
		switchLabel = new ASTSwitchLabel(); 
		if (la.kind == 12) {
			Get();
			tsym (t, depth); 
			ASTExpr expr ; 
			Expression(out expr);
			switchLabel.expression = expr; 
			Expect(87);
			tsym (t, depth); 
		} else if (la.kind == 20) {
			Get();
			tsym (t, depth); 
			Expect(87);
			tsym (t, depth); 
		} else SynErr(202);
		lntsym (); --depth; 
	}

	void QueryExpression() {
		ntsym ("QueryExpression", depth); 
		++depth; 
		enterContext(); 
		FromClause();
		QueryBody();
		leaveContext(); 
		lntsym (); --depth; 
	}

	void ImplicitLambdaExpression() {
		ntsym ("ImplicitLambdaExpression", depth); 
		++depth; 
		if (la.kind == 1) {
			ImplicitAnonymousFunctionParameter();
		} else if (la.kind == 99) {
			Get();
			tsym (t, depth); 
			if (la.kind == 1) {
				ImplicitAnonymousFunctionParameter();
				while (la.kind == 88) {
					Get();
					tsym (t, depth); 
					ImplicitAnonymousFunctionParameter();
				}
			}
			Expect(115);
			tsym (t, depth); 
		} else SynErr(203);
		Expect(85);
		tsym (t, depth); 
		ImplicitTypedLambdaBody();
		lntsym (); --depth; 
	}

	void AnonymousMethodParameter(out ASTAnonMethodParam amp) {
		TypeKind	dummy;
		ASTType		ty;
		
		ntsym ("AnonymousMethodParameter", depth); 
		++depth; 
		amp = new ASTAnonMethodParam(); 
		if (la.kind == 50 || la.kind == 57) {
			if (la.kind == 57) {
				Get();
				tsym (t, depth); 
				amp.isRef = true; 
			} else {
				Get();
				tsym (t, depth); 
				amp.isOut = true; 
			}
		}
		Type(out dummy, false, out ty);
		amp.type = ty; 
		Expect(1);
		tsym (t, depth); 
		amp.ident= t.val; 
		lntsym (); --depth; 
	}

	void NullCoalescingExpr(out ASTExpr e) {
		ntsym ("NullCoalescingExpr", depth); 
		++depth; 
		e = null; ASTExprUnary e2 = null; 
		OrExpr(ref e);
		while (la.kind == 108) {
			Get();
			tsym (t, depth); 
			ASTExprUnary exprUnary; 
			Unary(out e2);
			e = new ASTExprBinaryExpr (e, "??", e2); 
			OrExpr(ref e);
		}
		lntsym (); --depth; 
	}

	void OrExpr(ref ASTExpr e) {
		ntsym ("OrExpr", depth); 
		++depth; 
		ASTExprUnary e2 = null; 
		AndExpr(ref e);
		while (la.kind == 136) {
			Get();
			tsym (t, depth); 
			ASTExprUnary exprUnary; 
			Unary(out e2);
			e = new ASTExprBinaryExpr (e, "||", e2); 
			AndExpr(ref e);
		}
		lntsym (); --depth; 
	}

	void AndExpr(ref ASTExpr e) {
		ntsym ("AndExpr", depth); 
		++depth; 
		ASTExprUnary e2 = null; 
		BitOrExpr(ref e);
		while (la.kind == 121) {
			Get();
			tsym (t, depth); 
			ASTExprUnary exprUnary; 
			Unary(out e2);
			e = new ASTExprBinaryExpr (e, "&&", e2); 
			BitOrExpr(ref e);
		}
		lntsym (); --depth; 
	}

	void BitOrExpr(ref ASTExpr e) {
		ntsym ("BitOrExpr", depth); 
		++depth; 
		ASTExprUnary e2 = null; 
		BitXorExpr(ref e);
		while (la.kind == 137) {
			Get();
			tsym (t, depth); 
			ASTExprUnary exprUnary; 
			Unary(out e2);
			e = new ASTExprBinaryExpr (e, "|" , e2); 
			BitXorExpr(ref e);
		}
		lntsym (); --depth; 
	}

	void BitXorExpr(ref ASTExpr e) {
		ntsym ("BitXorExpr", depth); 
		++depth; 
		ASTExprUnary e2 = null; 
		BitAndExpr(ref e);
		while (la.kind == 138) {
			Get();
			tsym (t, depth); 
			ASTExprUnary exprUnary; 
			Unary(out e2);
			e = new ASTExprBinaryExpr (e, "^" , e2); 
			BitAndExpr(ref e);
		}
		lntsym (); --depth; 
	}

	void BitAndExpr(ref ASTExpr e) {
		ntsym ("BitAndExpr", depth); 
		++depth; 
		ASTExprUnary e2 = null; 
		EqlExpr(ref e);
		while (la.kind == 83) {
			Get();
			tsym (t, depth); 
			ASTExprUnary exprUnary; 
			Unary(out e2);
			e = new ASTExprBinaryExpr (e, "&" , e2); 
			EqlExpr(ref e);
		}
		lntsym (); --depth; 
	}

	void EqlExpr(ref ASTExpr e) {
		ntsym ("EqlExpr", depth); 
		++depth; 
		ASTExprUnary e2 = null; 
		RelExpr(ref e);
		while (la.kind == 93 || la.kind == 106) {
			string sOp; 
			if (la.kind == 106) {
				Get();
				tsym (t, depth); 
				sOp = "!="; 
			} else {
				Get();
				tsym (t, depth); 
				sOp = "=="; 
			}
			ASTExprUnary exprUnary; 
			Unary(out e2);
			e = new ASTExprBinaryExpr (e, sOp , e2); 
			RelExpr(ref e);
		}
		lntsym (); --depth; 
	}

	void RelExpr(ref ASTExpr e) {
		ntsym ("RelExpr", depth); 
		++depth; 
		ASTExprUnary e2 = null; string sOp = null; 
		ShiftExpr(ref e);
		while (StartOf(28)) {
			if (StartOf(29)) {
				if (la.kind == 101) {
					Get();
					tsym (t, depth); 
					sOp =  "<"; 
				} else if (la.kind == 94) {
					Get();
					tsym (t, depth); 
					sOp =  ">"; 
				} else if (la.kind == 122) {
					Get();
					tsym (t, depth); 
					sOp = "<="; 
				} else {
					Get();
					tsym (t, depth); 
					sOp = ">="; 
				}
				Unary(out e2);
				e = new ASTExprBinaryExpr (e, sOp, e2); 
				ShiftExpr(ref e);
			} else {
				if (la.kind == 42) {
					Get();
					tsym (t, depth); 
					sOp = "is"; 
				} else {
					Get();
					tsym (t, depth); 
					sOp = "as"; 
				}
				ASTResolvedType rs ; 
				ResolvedType(out rs);
				e = new ASTExprBinaryExpr (e, sOp, rs); 
			}
		}
		lntsym (); --depth; 
	}

	void ShiftExpr(ref ASTExpr e) {
		ntsym ("ShiftExpr", depth); 
		++depth; 
		ASTExprUnary e2 = null; string sOp = null; 
		AddExpr(ref e);
		while (IsShift()) {
			if (la.kind == 102) {
				Get();
				tsym (t, depth); 
				sOp = "<<"; 
			} else if (la.kind == 94) {
				Get();
				tsym (t, depth); 
				Expect(94);
				tsym (t, depth); 
				sOp = ">>"; 
			} else SynErr(204);
			ASTExprUnary exprUnary; 
			Unary(out e2);
			e = new ASTExprBinaryExpr (e, sOp , e2); 
			AddExpr(ref e);
		}
		lntsym (); --depth; 
	}

	void AddExpr(ref ASTExpr e) {
		ntsym ("AddExpr", depth); 
		++depth; 
		ASTExprUnary e2 = null; string sOp = null; 
		MulExpr(ref e);
		while (la.kind == 103 || la.kind == 110) {
			if (la.kind == 110) {
				Get();
				tsym (t, depth); 
				sOp = "+"; 
			} else {
				Get();
				tsym (t, depth); 
				sOp = "-"; 
			}
			ASTExprUnary exprUnary; 
			Unary(out e2);
			e = new ASTExprBinaryExpr (e, sOp , e2); 
			MulExpr(ref e);
		}
		lntsym (); --depth; 
	}

	void MulExpr(ref ASTExpr e) {
		ntsym ("MulExpr", depth); 
		++depth; 
		ASTExprUnary e2 = null; string sOp = null; 
		while (la.kind == 118 || la.kind == 139 || la.kind == 140) {
			if (la.kind == 118) {
				Get();
				tsym (t, depth); 
				sOp = "*"; 
			} else if (la.kind == 139) {
				Get();
				tsym (t, depth); 
				sOp = "/"; 
			} else {
				Get();
				tsym (t, depth); 
				sOp = "%"; 
			}
			Unary(out e2);
			e = new ASTExprBinaryExpr (e, sOp , e2); 
		}
		lntsym (); --depth; 
	}

	void Primary(out ASTExprPrim primary) {
		TypeKind			type;
		bool				isArrayCreation	= false;
		ASTTypeArgumentList	targs			= null;
		ASTType				ty;
		ASTArgument			argument;
		ASTExpr				expr;
		ASTBlock			block;
		
		ntsym ("Primary", depth); 
		++depth; 
		primary = null; 
		switch (la.kind) {
		case 2: case 3: case 4: case 5: case 29: case 47: case 70: {
			ASTExprPrimLit exprPrimLit; 
			Literal(out exprPrimLit);
			primary = exprPrimLit;
			break;
		}
		case 99: {
			Get();
			tsym (t, depth); 
			Expression(out expr);
			primary = new ASTExprPrimBtwnParens (expr); 
			Expect(115);
			tsym (t, depth); 
			break;
		}
		case 9: case 11: case 14: case 19: case 23: case 32: case 39: case 44: case 48: case 59: case 61: case 65: case 73: case 74: case 77: {
			primary = new ASTExprPrimType(); 
			switch (la.kind) {
			case 9: {
				Get();
				break;
			}
			case 11: {
				Get();
				break;
			}
			case 14: {
				Get();
				break;
			}
			case 19: {
				Get();
				break;
			}
			case 23: {
				Get();
				break;
			}
			case 32: {
				Get();
				break;
			}
			case 39: {
				Get();
				break;
			}
			case 44: {
				Get();
				break;
			}
			case 48: {
				Get();
				break;
			}
			case 59: {
				Get();
				break;
			}
			case 61: {
				Get();
				break;
			}
			case 65: {
				Get();
				break;
			}
			case 73: {
				Get();
				break;
			}
			case 74: {
				Get();
				break;
			}
			case 77: {
				Get();
				break;
			}
			}
			tsym (t, depth); 
			((ASTExprPrimType)primary).sPrimitiveType = t.val; 
			if (la.kind == 91) {
				Get();
				tsym (t, depth); 
				Expect(1);
				tsym (t, depth); 
				((ASTExprPrimType)primary).ident = t.val; 
				if (IsGeneric()) {
					TypeArgumentList(out targs);
					((ASTExprPrimType)primary).typeArgumentList.AddRange(targs); 
				}
			}
			break;
		}
		case 1: {
			Get();
			tsym (t, depth); 
			primary = new ASTExprPrimName(); ((ASTExprPrimName)primary).ident = t.val; 
			if (la.kind == 92) {
				Get();
				tsym (t, depth); 
				Expect(1);
				tsym (t, depth); 
				((ASTExprPrimName)primary).afterDblColonIdent = t.val; 
				if (la.kind == 101) {
					TypeArgumentList(out targs);
					((ASTExprPrimName)primary).afterDblColonTargs.AddRange(targs); 
				}
				Expect(91);
				tsym (t, depth); 
				Expect(1);
				tsym (t, depth); 
				((ASTExprPrimName)primary).afterDotIdent = t.val; 
			}
			if (IsGeneric()) {
				TypeArgumentList(out targs);
				((ASTExprPrimName)primary).afterDotTargs.AddRange(targs); 
			}
			break;
		}
		case 68: {
			Get();
			tsym (t, depth); 
			primary = new ASTExprPrimThis(); 
			break;
		}
		case 8: {
			Get();
			tsym (t, depth); 
			primary = new ASTExprPrimBase(); 
			break;
		}
		case 46: {
			Get();
			tsym (t, depth); 
			primary = new ASTExprPrimNew (); 
			if (StartOf(16)) {
				Type(out type, false, out ty);
				primary = new ASTExprPrimNewTypeArgs(); ((ASTExprPrimNewTypeArgs)primary).type = ty; 
				if (la.kind == 99) {
					Get();
					tsym (t, depth); 
					if (StartOf(15)) {
						Argument(out argument);
						((ASTExprPrimNewTypeArgs)primary).args.Add(argument); 
						while (la.kind == 88) {
							Get();
							tsym (t, depth); 
							Argument(out argument);
							((ASTExprPrimNewTypeArgs)primary).args.Add(argument); 
						}
					}
					Expect(115);
					tsym (t, depth); 
					if (la.kind == 97) {
						ASTObjectOrCollecInit oci; 
						ObjectOrCollectionInitializer(out oci);
						((ASTExprPrimNewTypeArgs)primary).oci = oci; 
					}
				} else if (la.kind == _lbrace && type != TypeKind.array) {
					ASTObjectOrCollecInit oci; 
					ObjectOrCollectionInitializer(out oci);
					primary = new ASTExprPrimNewObjInit();
					((ASTExprPrimNewObjInit)primary).oci = oci;
					((ASTExprPrimNewObjInit)primary).type = ty;
					
				} else if (la.kind == 98) {
					int dims = 1;	
					Get();
					tsym (t, depth);	
					Expression(out expr);
					while (la.kind == 88) {
						Get();
						tsym (t, depth);	
						Expression(out expr);
						++dims;			
					}
					Expect(114);
					tsym (t, depth);	
					while (IsDims()) {
						Expect(98);
						tsym (t, depth);	
						dims = 1; 
						while (la.kind == 88) {
							Get();
							tsym (t, depth);	
							++dims;	
						}
						Expect(114);
						tsym (t, depth);	
					}
					isArrayCreation = true; 
					if (la.kind == 97) {
						ArrayInitializer();
						isArrayCreation = false;
						/*	From the specification point of view (14.5.6) this would be an
						array creation expression, but csc does allow element access
						on an initialized array creation expression so we allow it too.
						The same holds for the ArrayInitializer only alternative below.
						*/
						
					}
				} else if (la.kind == 97) {
					ArrayInitializer();
					if (type != TypeKind.array) Error("array type expected"); isArrayCreation = true; 
				} else SynErr(205);
			} else if (la.kind == 97) {
				AnonymousObjectInitializer();
			} else if (la.kind == 98) {
				int dims = 1;	
				Get();
				tsym (t, depth);	
				while (la.kind == 88) {
					Get();
					tsym (t, depth);	
					dims++; 
				}
				Expect(114);
				tsym (t, depth);	
				ArrayInitializer();
				isArrayCreation = true; 
			} else SynErr(206);
			break;
		}
		case 72: {
			Get();
			tsym (t, depth);	
			Expect(99);
			tsym (t, depth);	
			Type(out type, true, out ty);
			primary = new ASTExprPrimTypeof(ty); 
			Expect(115);
			tsym (t, depth);	
			break;
		}
		case 15: {
			Get();
			tsym (t, depth);	
			Expect(99);
			tsym (t, depth);	
			Expression(out expr);
			primary = new ASTExprPrimChecked(expr); 
			Expect(115);
			tsym (t, depth);	
			break;
		}
		case 75: {
			Get();
			tsym (t, depth);	
			Expect(99);
			tsym (t, depth);	
			Expression(out expr);
			primary = new ASTExprPrimUnchecked(expr); 
			Expect(115);
			tsym (t, depth);	
			break;
		}
		case 20: {
			Get();
			tsym (t, depth);	
			Expect(99);
			tsym (t, depth);	
			Type(out type, true, out ty);
			primary = new ASTExprPrimDefault(ty); 
			Expect(115);
			tsym (t, depth);	
			break;
		}
		case 21: {
			Get();
			tsym (t, depth);	
			primary = new ASTExprPrimDelegate(); 
			if (la.kind == 99) {
				Get();
				tsym (t, depth);	
				((ASTExprPrimDelegate)primary).hasParens = true; 
				if (StartOf(18)) {
					ASTAnonMethodParam amp; 
					AnonymousMethodParameter(out amp);
					((ASTExprPrimDelegate)primary).parameters.Add(amp); 
					while (la.kind == 88) {
						Get();
						tsym (t, depth);	
						AnonymousMethodParameter(out amp);
						((ASTExprPrimDelegate)primary).parameters.Add(amp); 
					}
				}
				Expect(115);
				tsym (t, depth);	
			}
			Block(out block);
			((ASTExprPrimDelegate)primary).block = block; 
			break;
		}
		case 62: {
			Get();
			tsym (t, depth);	
			Expect(99);
			tsym (t, depth);	
			Type(out type, false, out ty);
			primary = new ASTExprPrimSizeof(ty); 
			Expect(115);
			tsym (t, depth);	
			break;
		}
		default: SynErr(207); break;
		}
		while (StartOf(30)) {
			switch (la.kind) {
			case 96: {
				Get();
				tsym (t, depth);	
				primary.tails.Add(new ASTExprPrimTailIncr()); 
				break;
			}
			case 89: {
				Get();
				tsym (t, depth);	
				primary.tails.Add(new ASTExprPrimTailDecr()); 
				break;
			}
			case 141: {
				Get();
				tsym (t, depth);	
				ASTExprPrimTailArrow tailArrow = new ASTExprPrimTailArrow(); 
				Expect(1);
				tsym (t, depth);	
				tailArrow.ident = t.val; 		
				if (IsGeneric()) {
					TypeArgumentList(out targs);
					tailArrow.targs.AddRange(targs); 
				}
				primary.tails.Add(tailArrow); 	
				break;
			}
			case 91: {
				Get();
				tsym (t, depth);	
				ASTExprPrimTailDot tailDot = new ASTExprPrimTailDot(); 
				Expect(1);
				tsym (t, depth);	
				tailDot.ident = t.val; 			
				if (IsGeneric()) {
					TypeArgumentList(out targs);
					tailDot.targs.AddRange(targs); 	
				}
				primary.tails.Add(tailDot); 		
				break;
			}
			case 99: {
				Get();
				tsym (t, depth);	
				ASTExprPrimTailArgs tailArgs = new ASTExprPrimTailArgs(); 
				if (StartOf(15)) {
					Argument(out argument);
					tailArgs.args.Add(argument); 
					while (la.kind == 88) {
						Get();
						tsym (t, depth);	
						Argument(out argument);
						tailArgs.args.Add(argument); 
					}
				}
				Expect(115);
				tsym (t, depth);	
				primary.tails.Add(tailArgs); 		
				break;
			}
			case 98: {
				if (isArrayCreation) Error("element access not allowed on array creation"); 
				Get();
				tsym (t, depth);	
				ASTExprPrimTailArray tailArray = new ASTExprPrimTailArray(); 
				Expression(out expr);
				tailArray.exprs.Add(expr); 
				while (la.kind == 88) {
					Get();
					tsym (t, depth);	
					Expression(out expr);
					tailArray.exprs.Add(expr); 
				}
				Expect(114);
				tsym (t, depth);	
				primary.tails.Add(tailArray); 
				break;
			}
			}
		}
		lntsym (); --depth; 
	}

	void Literal(out ASTExprPrimLit exprPrimLit) {
		ntsym ("Literal", depth); 
		++depth; 
		exprPrimLit = null; 
		switch (la.kind) {
		case 2: {
			Get();
			tsym (t, depth); 
			exprPrimLit = new ASTExprPrimLit(ASTExprPrimLitType.INT	, t.val); 
			break;
		}
		case 3: {
			Get();
			tsym (t, depth); 
			exprPrimLit = new ASTExprPrimLit(ASTExprPrimLitType.REAL	, t.val); 
			break;
		}
		case 4: {
			Get();
			tsym (t, depth); 
			exprPrimLit = new ASTExprPrimLit(ASTExprPrimLitType.CHAR	, t.val); 
			break;
		}
		case 5: {
			Get();
			tsym (t, depth); 
			exprPrimLit = new ASTExprPrimLit(ASTExprPrimLitType.STRING,t.val); 
			break;
		}
		case 70: {
			Get();
			tsym (t, depth); 
			exprPrimLit = new ASTExprPrimLit(ASTExprPrimLitType.TRUE	, t.val); 
			break;
		}
		case 29: {
			Get();
			tsym (t, depth); 
			exprPrimLit = new ASTExprPrimLit(ASTExprPrimLitType.FALSE, t.val); 
			break;
		}
		case 47: {
			Get();
			tsym (t, depth); 
			exprPrimLit = new ASTExprPrimLit(ASTExprPrimLitType.NULL	, t.val); 
			break;
		}
		default: SynErr(208); break;
		}
		lntsym (); --depth; 
	}

	void ObjectOrCollectionInitializer(out ASTObjectOrCollecInit oci) {
		ntsym ("ObjectOrCollectionInitializer", depth); 
		++depth; 
		Expect(97);
		tsym (t, depth); 
		oci = new ASTObjectOrCollecInit(); 
		ASTMemberOrElemInit mei; 
		if (StartOf(31)) {
			MemberOrElementInitializer(out mei);
			oci.memberInits.Add(mei); 
			while (la.kind == _comma && Peek(1).kind != _rbrace) {
				Expect(88);
				tsym (t, depth); 
				MemberOrElementInitializer(out mei);
				oci.memberInits.Add(mei); 
			}
			if (la.kind == 88) {
				Get();
				tsym (t, depth); 
				oci.hasFinalComma = true; 
			}
		}
		Expect(113);
		tsym (t, depth); 
		lntsym (); --depth; 
	}

	void AnonymousObjectInitializer() {
		ntsym ("AnonymousObjectInitializer", depth); 
		++depth; 
		Expect(97);
		tsym (t, depth); 
		if (StartOf(19)) {
			MemberDeclaratorList();
		}
		Expect(113);
		tsym (t, depth); 
		lntsym (); --depth; 
	}

	void MemberDeclaratorList() {
		ntsym ("MemberDeclaratorList", depth); 
		++depth; 
		MemberDeclarator();
		if (la.kind == 88) {
			Get();
			tsym (t, depth); 
			if (StartOf(19)) {
				MemberDeclaratorList();
			}
		}
		lntsym (); --depth; 
	}

	void MemberDeclarator() {
		ntsym ("MemberDeclarator", depth); 
		++depth; 
		ASTExpr expr ; 
		if (IsAssignment()) {
			Expect(1);
			tsym (t, depth); 
			Expect(86);
			tsym (t, depth); 
		}
		Expression(out expr);
		lntsym (); --depth; 
	}

	void MemberOrElementInitializer(out ASTMemberOrElemInit mei) {
		mei = null; 
		ASTExpr expr; ASTObjectOrCollecInit oci; ASTArgument arg; 
		if (IsAssignment()) {
			mei = new ASTMemberOrElemInitNormal(); 
			Expect(1);
			((ASTMemberOrElemInitNormal)mei).ident = t.val; 
			Expect(86);
			if (StartOf(19)) {
				Expression(out expr);
				((ASTMemberOrElemInitNormal)mei).expr  = expr ; 
			} else if (la.kind == 97) {
				ObjectOrCollectionInitializer(out oci);
				((ASTMemberOrElemInitNormal)mei).oci   = oci  ; 
			} else SynErr(209);
		} else if (StartOf(31)) {
			if (StartOf(15)) {
				mei = new ASTMemberOrElemInitArgs(); 
				Argument(out arg);
				((ASTMemberOrElemInitArgs)mei).args.Add(arg); 
			} else {
				mei = new ASTMemberOrElemInitArgs(); 
				Get();
				Argument(out arg);
				((ASTMemberOrElemInitArgs)mei).args.Add(arg); 
				while (la.kind == 88) {
					Get();
					Argument(out arg);
					((ASTMemberOrElemInitArgs)mei).args.Add(arg); 
				}
				Expect(113);
			}
		} else SynErr(210);
	}

	void ImplicitAnonymousFunctionParameter() {
		ntsym ("ImplicitAnonymousFunctionParameter", depth); 
		++depth; 
		Expect(1);
		tsym (t, depth); 
		lntsym (); --depth; 
	}

	void ImplicitTypedLambdaBody() {
		ntsym ("ImplicitTypedLambdaBody", depth); 
		++depth; 
		ASTExpr	expr ;
		ASTBlock		block;
		
		if (la.kind == 97) {
			Block(out block);
		} else if (StartOf(19)) {
			Expression(out expr);
		} else SynErr(211);
		lntsym (); --depth; 
	}

	void FromClause() {
		TypeKind	type;
		ASTType		ty;
		
		ntsym ("FromClause", depth); 
		++depth; 
		ASTExpr expr ; 
		Expect(123);
		tsym (t, depth); 
		if (Peek(1).kind != _in) {
			Type(out type, false, out ty);
		}
		Expect(1);
		tsym (t, depth); 
		Expect(38);
		tsym (t, depth); 
		Expression(out expr);
		lntsym (); --depth; 
	}

	void QueryBody() {
		ntsym ("QueryBody", depth); 
		++depth; 
		while (StartOf(32)) {
			QueryBodyClause();
		}
		if (la.kind == 133) {
			SelectClause();
		} else if (la.kind == 134) {
			GroupClause();
		} else SynErr(212);
		if (la.kind == 128) {
			Get();
			tsym (t, depth); 
			Expect(1);
			tsym (t, depth); 
			QueryBody();
		}
		lntsym (); --depth; 
	}

	void QueryBodyClause() {
		ntsym ("QueryBodyClause", depth); 
		++depth; 
		if (la.kind == 123) {
			FromClause();
		} else if (la.kind == 129) {
			LetClause();
		} else if (la.kind == 124) {
			WhereClause();
		} else if (la.kind == 125) {
			JoinClause();
		} else if (la.kind == 130) {
			OrderByClause();
		} else SynErr(213);
		lntsym (); --depth; 
	}

	void SelectClause() {
		ntsym ("SelectClause", depth); 
		++depth; 
		ASTExpr expr ; 
		Expect(133);
		tsym (t, depth); 
		Expression(out expr);
		lntsym (); --depth; 
	}

	void GroupClause() {
		ntsym ("GroupClause", depth); 
		++depth; 
		ASTExpr expr ; 
		Expect(134);
		tsym (t, depth); 
		Expression(out expr);
		Expect(135);
		tsym (t, depth); 
		Expression(out expr);
		lntsym (); --depth; 
	}

	void LetClause() {
		ntsym ("LetClause", depth); 
		++depth; 
		ASTExpr expr ; 
		Expect(129);
		tsym (t, depth); 
		Expect(1);
		tsym (t, depth); 
		Expect(86);
		tsym (t, depth); 
		Expression(out expr);
		lntsym (); --depth; 
	}

	void WhereClause() {
		ntsym ("LetClause", depth); 
		++depth; 
		ASTExpr expr ; 
		Expect(124);
		tsym (t, depth); 
		Expression(out expr);
		lntsym (); --depth; 
	}

	void JoinClause() {
		TypeKind	type;
		ASTType		ty;
		
		ntsym ("JoinClause", depth); 
		++depth; 
		ASTExpr expr ; 
		Expect(125);
		tsym (t, depth); 
		if (Peek(1).kind != _in) {
			Type(out type, false, out ty);
		}
		Expect(1);
		tsym (t, depth); 
		Expect(38);
		tsym (t, depth); 
		Expression(out expr);
		Expect(126);
		tsym (t, depth); 
		Expression(out expr);
		Expect(127);
		tsym (t, depth); 
		Expression(out expr);
		if (la.kind == 128) {
			Get();
			tsym (t, depth); 
			Expect(1);
			tsym (t, depth); 
		}
		lntsym (); --depth; 
	}

	void OrderByClause() {
		ntsym ("OrderByClause", depth); 
		++depth; 
		Expect(130);
		tsym (t, depth); 
		Ordering();
		while (la.kind == 88) {
			Get();
			tsym (t, depth); 
			Ordering();
		}
		lntsym (); --depth; 
	}

	void Ordering() {
		ntsym ("Ordering", depth); 
		++depth; 
		ASTExpr expr ; 
		Expression(out expr);
		if (la.kind == 131 || la.kind == 132) {
			if (la.kind == 131) {
				Get();
			} else {
				Get();
			}
		}
		lntsym (); --depth; 
	}



	public void Parse() {
		la = new Token();
		la.val = "";		
		Get();
		CS3();
		Expect(0);

	}
	
	static readonly bool[,] set = {
		{T,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x},
		{x,T,x,x, x,x,T,x, x,x,x,x, x,x,x,x, T,x,x,x, x,T,x,x, x,T,x,x, T,x,x,x, x,x,x,x, x,x,x,x, T,T,x,x, x,T,T,x, x,x,x,T, x,T,T,T, T,x,x,x, T,x,x,x, T,x,T,x, x,x,x,x, x,x,x,x, T,x,x,T, x,T,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,T,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x},
		{x,T,x,x, x,x,T,x, x,x,x,x, x,x,x,x, T,x,x,x, x,T,x,x, x,T,x,x, T,x,x,x, x,x,x,x, x,x,x,x, T,T,x,x, x,x,T,x, x,x,x,T, x,T,T,T, T,x,x,x, T,x,x,x, T,x,T,x, x,x,x,x, x,x,x,x, T,x,x,T, x,T,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,T,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x},
		{x,x,x,x, x,x,T,T, T,T,T,T, T,T,T,T, T,T,T,T, T,T,T,T, T,T,T,T, T,T,T,T, T,T,T,T, T,T,T,T, T,T,T,T, T,T,T,T, T,T,T,T, T,T,T,T, T,T,T,T, T,T,T,T, T,T,T,T, T,T,T,T, T,T,T,T, T,T,T,T, T,T,T,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x},
		{x,x,x,x, x,x,T,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, T,x,x,x, x,x,x,x, x,x,x,x, x,T,x,x, x,x,T,x, x,x,x,T, x,T,T,T, T,x,x,x, T,x,x,x, T,x,x,x, x,x,x,x, x,x,x,x, T,x,x,T, x,T,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x},
		{x,T,x,x, x,x,x,x, x,x,x,x, x,x,x,x, T,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, T,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,T,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x},
		{x,T,x,x, x,x,x,x, x,T,x,T, x,x,T,x, x,x,x,T, x,x,x,T, x,x,x,x, x,x,x,x, T,x,x,x, x,x,x,T, x,x,x,x, T,x,x,x, T,x,T,x, T,x,x,x, x,T,x,T, x,T,x,x, x,T,x,x, T,x,x,x, x,T,T,x, x,T,x,x, T,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,T,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x},
		{x,T,x,x, x,x,x,x, x,x,x,x, x,x,x,x, T,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, T,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,T,T,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x},
		{x,T,x,x, x,x,T,x, x,T,x,T, x,x,T,x, T,T,x,T, x,T,x,T, x,T,T,T, T,x,x,T, T,x,x,x, x,T,x,T, T,T,x,x, T,x,T,x, T,x,x,T, x,T,T,T, T,x,x,T, T,T,x,x, T,T,T,x, x,x,x,x, x,T,T,x, T,T,x,T, T,T,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,T,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,T,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x},
		{x,T,x,x, x,x,T,x, x,T,x,T, x,x,T,x, T,T,x,T, x,T,x,T, x,T,T,T, T,x,x,T, T,x,x,x, x,T,x,T, T,T,x,x, T,x,T,x, T,x,x,T, x,T,T,T, T,x,x,T, T,T,x,x, T,T,T,x, x,x,x,x, x,T,T,x, T,T,x,T, T,T,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,T,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x},
		{x,T,x,x, x,x,x,x, x,T,x,T, x,x,T,x, x,x,x,T, x,x,x,T, x,x,T,x, x,x,x,x, T,x,x,x, x,x,x,T, x,x,x,x, T,x,T,x, T,x,x,x, x,x,x,x, x,x,x,T, x,T,x,x, x,T,x,x, x,x,x,x, x,T,T,x, T,T,x,x, T,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,T,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x},
		{x,x,x,x, x,x,x,x, x,T,x,T, x,x,T,x, x,x,x,T, x,x,x,T, x,x,x,x, x,x,x,x, T,x,x,x, x,x,x,T, x,x,x,x, T,x,x,x, x,x,x,x, x,x,x,x, x,x,x,T, x,T,x,x, x,x,x,x, x,x,x,x, x,T,T,x, x,T,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x},
		{x,T,x,x, x,x,x,x, x,T,x,T, x,x,T,x, x,x,x,T, x,x,x,T, x,x,x,x, x,x,x,x, T,x,x,x, x,x,x,T, x,x,x,x, T,x,x,x, T,x,T,x, x,x,x,x, x,T,x,T, x,T,x,x, x,T,x,x, T,x,x,x, x,T,T,x, x,T,x,x, T,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x},
		{x,T,x,x, x,x,x,x, x,T,x,T, x,x,T,x, T,T,x,T, x,T,x,T, x,T,T,T, x,x,x,T, T,x,x,x, x,T,x,T, T,x,x,x, T,x,x,x, T,x,x,x, x,x,x,x, x,x,x,T, x,T,x,x, x,T,T,x, x,x,x,x, x,T,T,x, x,T,x,x, T,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x},
		{x,T,x,x, x,x,x,x, x,T,x,T, x,x,T,x, x,x,x,T, x,x,x,T, x,x,x,x, x,x,x,x, T,x,x,x, x,x,x,T, x,x,x,x, T,x,T,x, T,x,x,x, x,x,x,x, x,x,x,T, x,T,x,x, x,T,x,x, x,x,x,x, x,T,T,x, T,T,x,x, T,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x},
		{x,T,T,T, T,T,x,x, T,T,x,T, x,x,T,T, x,x,x,T, T,T,x,T, x,x,x,x, x,T,x,x, T,x,x,x, x,x,x,T, x,x,x,x, T,x,T,T, T,x,T,x, x,x,x,x, x,T,x,T, x,T,T,x, x,T,x,x, T,x,T,x, T,T,T,T, x,T,x,x, x,x,x,T, x,x,x,x, x,T,x,x, x,x,x,x, T,x,x,T, x,x,x,T, x,x,x,T, x,x,T,x, x,x,x,x, x,T,T,x, x,x,x,T, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x},
		{x,T,x,x, x,x,x,x, x,T,x,T, x,x,T,x, x,x,x,T, x,x,x,T, x,x,x,x, x,x,x,x, T,x,x,x, x,x,x,T, x,x,x,x, T,x,x,x, T,x,x,x, x,x,x,x, x,x,x,T, x,T,x,x, x,T,x,x, x,x,x,x, x,T,T,x, x,T,x,x, T,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x},
		{x,T,T,T, T,T,x,x, T,T,T,T, x,x,T,T, x,T,T,T, T,T,T,T, x,x,x,x, x,T,x,T, T,T,T,T, T,x,x,T, x,x,x,T, T,x,T,T, T,x,x,x, x,x,x,x, x,x,T,T, x,T,T,x, x,T,x,T, T,T,T,T, T,T,T,T, T,T,T,x, T,x,T,T, x,x,x,x, x,T,x,x, x,x,x,x, T,T,x,T, x,x,x,T, x,x,x,T, x,x,T,x, x,x,x,x, T,T,T,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x},
		{x,T,x,x, x,x,x,x, x,T,x,T, x,x,T,x, x,x,x,T, x,x,x,T, x,x,x,x, x,x,x,x, T,x,x,x, x,x,x,T, x,x,x,x, T,x,x,x, T,x,T,x, x,x,x,x, x,T,x,T, x,T,x,x, x,T,x,x, x,x,x,x, x,T,T,x, x,T,x,x, T,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x},
		{x,T,T,T, T,T,x,x, T,T,x,T, x,x,T,T, x,x,x,T, T,T,x,T, x,x,x,x, x,T,x,x, T,x,x,x, x,x,x,T, x,x,x,x, T,x,T,T, T,x,x,x, x,x,x,x, x,x,x,T, x,T,T,x, x,T,x,x, T,x,T,x, T,T,T,T, x,T,x,x, x,x,x,T, x,x,x,x, x,T,x,x, x,x,x,x, T,x,x,T, x,x,x,T, x,x,x,T, x,x,T,x, x,x,x,x, x,T,T,x, x,x,x,T, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x},
		{x,T,T,T, T,T,x,x, T,T,x,T, x,x,T,T, x,x,x,T, T,T,x,T, x,x,x,x, x,T,x,x, T,x,x,x, x,x,x,T, x,x,x,x, T,x,T,T, T,x,x,x, x,x,x,x, x,x,x,T, x,T,T,x, x,T,x,x, T,x,T,x, T,T,T,T, x,T,x,x, x,x,x,T, x,x,x,x, x,T,x,x, x,x,x,x, T,x,x,T, x,x,x,T, x,x,x,T, x,x,T,x, x,x,x,x, x,T,T,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x},
		{x,x,x,x, x,x,x,T, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,T,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,T, x,x,x,T, T,x,x,x, x,T,T,T, x,x,x,x, x,T,T,T, x,x,T,x, T,x,T,x, T,T,T,T, T,x,T,x, x,T,T,T, T,T,T,T, T,T,T,T, T,T,T,T, T,T,T,T, T,x,x,x},
		{x,T,x,x, x,x,T,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, T,x,x,x, x,x,x,x, x,x,x,x, x,T,x,x, x,x,T,x, x,x,x,T, x,T,T,T, T,x,x,x, T,x,x,x, T,x,x,x, x,x,x,x, x,x,x,x, T,x,x,T, x,T,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,T,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x},
		{x,T,T,T, T,T,x,x, T,T,x,T, x,x,T,T, x,x,x,T, T,T,x,T, x,x,x,x, x,T,x,x, T,x,x,x, x,x,x,T, x,x,x,x, T,x,T,T, T,x,x,x, x,x,x,x, x,x,x,T, x,T,T,x, x,T,x,x, T,x,T,x, T,T,T,T, x,T,x,x, x,x,x,T, x,x,x,x, x,T,x,x, x,x,x,x, T,T,x,T, x,x,x,T, x,x,x,T, x,x,T,x, x,x,x,x, x,T,T,x, x,x,x,T, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x},
		{x,x,x,x, x,x,x,x, x,x,x,T, x,x,T,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,T, x,x,x,x, T,x,x,x, x,x,x,x, x,x,x,x, x,x,x,T, x,T,x,x, x,x,x,x, x,x,x,x, x,T,T,x, x,T,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x},
		{x,T,T,T, T,T,x,x, T,T,T,T, x,x,T,T, x,x,T,T, T,T,T,T, x,x,x,x, x,T,x,T, T,T,T,T, T,x,x,T, x,x,x,T, T,x,T,T, T,x,x,x, x,x,x,x, x,x,T,T, x,T,T,x, x,T,x,T, T,T,T,T, T,T,T,T, T,T,T,x, x,x,T,T, x,x,x,x, x,T,x,x, x,x,x,x, T,T,x,T, x,x,x,T, x,x,x,T, x,x,T,x, x,x,x,x, T,T,T,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x},
		{x,T,T,T, T,T,x,x, T,T,x,T, x,x,T,T, x,x,x,T, T,T,x,T, x,x,x,x, x,T,x,x, T,x,x,x, x,x,x,T, x,x,x,x, T,x,T,T, T,x,x,x, x,x,x,x, x,x,x,T, x,T,T,x, x,T,x,x, T,x,T,x, T,T,T,T, x,T,x,x, T,x,x,T, x,x,x,x, x,T,x,x, x,x,x,x, T,x,x,T, x,x,x,T, x,x,x,T, x,x,T,x, x,x,x,x, x,T,T,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x},
		{x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, T,x,T,x, x,x,T,x, x,x,T,x, x,x,x,x, T,x,x,x, T,T,x,x, x,T,x,T, x,x,x,x, x,x,x,T, T,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x},
		{x,x,x,x, x,x,x,T, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,T,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,T,T, x,x,x,x, x,T,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,T,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x},
		{x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,T,T, x,x,x,x, x,T,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,T,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x},
		{x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,T,x,T, x,x,x,x, T,x,T,T, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,T,x,x},
		{x,T,T,T, T,T,x,x, T,T,x,T, x,x,T,T, x,x,x,T, T,T,x,T, x,x,x,x, x,T,x,x, T,x,x,x, x,x,x,T, x,x,x,x, T,x,T,T, T,x,T,x, x,x,x,x, x,T,x,T, x,T,T,x, x,T,x,x, T,x,T,x, T,T,T,T, x,T,x,x, x,x,x,T, x,x,x,x, x,T,x,x, x,x,x,x, T,T,x,T, x,x,x,T, x,x,x,T, x,x,T,x, x,x,x,x, x,T,T,x, x,x,x,T, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x},
		{x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,T, T,T,x,x, x,T,T,x, x,x,x,x, x,x,x,x, x,x,x,x}

	};
} // end Parser


public class Errors {
	public int count = 0;                                    // number of errors detected
	public System.IO.TextWriter errorStream = Console.Out;   // error messages go to this stream
	public string errMsgFormat = "-- line {0} col {1}: {2}"; // 0=line, 1=column, 2=text

	public virtual void SynErr (int line, int col, int n) {
		string s;
		switch (n) {
			case 0: s = "EOF expected"; break;
			case 1: s = "ident expected"; break;
			case 2: s = "intCon expected"; break;
			case 3: s = "realCon expected"; break;
			case 4: s = "charCon expected"; break;
			case 5: s = "stringCon expected"; break;
			case 6: s = "abstract expected"; break;
			case 7: s = "as expected"; break;
			case 8: s = "base expected"; break;
			case 9: s = "bool expected"; break;
			case 10: s = "break expected"; break;
			case 11: s = "byte expected"; break;
			case 12: s = "case expected"; break;
			case 13: s = "catch expected"; break;
			case 14: s = "char expected"; break;
			case 15: s = "checked expected"; break;
			case 16: s = "class expected"; break;
			case 17: s = "const expected"; break;
			case 18: s = "continue expected"; break;
			case 19: s = "decimal expected"; break;
			case 20: s = "default expected"; break;
			case 21: s = "delegate expected"; break;
			case 22: s = "do expected"; break;
			case 23: s = "double expected"; break;
			case 24: s = "else expected"; break;
			case 25: s = "enum expected"; break;
			case 26: s = "event expected"; break;
			case 27: s = "explicit expected"; break;
			case 28: s = "extern expected"; break;
			case 29: s = "false expected"; break;
			case 30: s = "finally expected"; break;
			case 31: s = "fixed expected"; break;
			case 32: s = "float expected"; break;
			case 33: s = "for expected"; break;
			case 34: s = "foreach expected"; break;
			case 35: s = "goto expected"; break;
			case 36: s = "if expected"; break;
			case 37: s = "implicit expected"; break;
			case 38: s = "in expected"; break;
			case 39: s = "int expected"; break;
			case 40: s = "interface expected"; break;
			case 41: s = "internal expected"; break;
			case 42: s = "is expected"; break;
			case 43: s = "lock expected"; break;
			case 44: s = "long expected"; break;
			case 45: s = "namespace expected"; break;
			case 46: s = "new expected"; break;
			case 47: s = "null expected"; break;
			case 48: s = "object expected"; break;
			case 49: s = "operator expected"; break;
			case 50: s = "outKW expected"; break;
			case 51: s = "override expected"; break;
			case 52: s = "params expected"; break;
			case 53: s = "private expected"; break;
			case 54: s = "protected expected"; break;
			case 55: s = "public expected"; break;
			case 56: s = "readonly expected"; break;
			case 57: s = "ref expected"; break;
			case 58: s = "return expected"; break;
			case 59: s = "sbyte expected"; break;
			case 60: s = "sealed expected"; break;
			case 61: s = "short expected"; break;
			case 62: s = "sizeof expected"; break;
			case 63: s = "stackalloc expected"; break;
			case 64: s = "static expected"; break;
			case 65: s = "string expected"; break;
			case 66: s = "struct expected"; break;
			case 67: s = "switch expected"; break;
			case 68: s = "this expected"; break;
			case 69: s = "throw expected"; break;
			case 70: s = "true expected"; break;
			case 71: s = "try expected"; break;
			case 72: s = "typeof expected"; break;
			case 73: s = "uint expected"; break;
			case 74: s = "ulong expected"; break;
			case 75: s = "unchecked expected"; break;
			case 76: s = "unsafe expected"; break;
			case 77: s = "ushort expected"; break;
			case 78: s = "usingKW expected"; break;
			case 79: s = "virtual expected"; break;
			case 80: s = "void expected"; break;
			case 81: s = "volatile expected"; break;
			case 82: s = "while expected"; break;
			case 83: s = "and expected"; break;
			case 84: s = "andassgn expected"; break;
			case 85: s = "arrow expected"; break;
			case 86: s = "assgn expected"; break;
			case 87: s = "colon expected"; break;
			case 88: s = "comma expected"; break;
			case 89: s = "dec expected"; break;
			case 90: s = "divassgn expected"; break;
			case 91: s = "dot expected"; break;
			case 92: s = "dblcolon expected"; break;
			case 93: s = "eq expected"; break;
			case 94: s = "gt expected"; break;
			case 95: s = "gteq expected"; break;
			case 96: s = "inc expected"; break;
			case 97: s = "lbrace expected"; break;
			case 98: s = "lbrack expected"; break;
			case 99: s = "lpar expected"; break;
			case 100: s = "lshassgn expected"; break;
			case 101: s = "lt expected"; break;
			case 102: s = "ltlt expected"; break;
			case 103: s = "minus expected"; break;
			case 104: s = "minusassgn expected"; break;
			case 105: s = "modassgn expected"; break;
			case 106: s = "neq expected"; break;
			case 107: s = "not expected"; break;
			case 108: s = "nullCoal expected"; break;
			case 109: s = "orassgn expected"; break;
			case 110: s = "plus expected"; break;
			case 111: s = "plusassgn expected"; break;
			case 112: s = "question expected"; break;
			case 113: s = "rbrace expected"; break;
			case 114: s = "rbrack expected"; break;
			case 115: s = "rpar expected"; break;
			case 116: s = "scolon expected"; break;
			case 117: s = "tilde expected"; break;
			case 118: s = "times expected"; break;
			case 119: s = "timesassgn expected"; break;
			case 120: s = "xorassgn expected"; break;
			case 121: s = "andand expected"; break;
			case 122: s = "lteq expected"; break;
			case 123: s = "from expected"; break;
			case 124: s = "where expected"; break;
			case 125: s = "join expected"; break;
			case 126: s = "on expected"; break;
			case 127: s = "equals expected"; break;
			case 128: s = "into expected"; break;
			case 129: s = "let expected"; break;
			case 130: s = "orderby expected"; break;
			case 131: s = "ascending expected"; break;
			case 132: s = "descending expected"; break;
			case 133: s = "select expected"; break;
			case 134: s = "group expected"; break;
			case 135: s = "by expected"; break;
			case 136: s = "\"||\" expected"; break;
			case 137: s = "\"|\" expected"; break;
			case 138: s = "\"^\" expected"; break;
			case 139: s = "\"/\" expected"; break;
			case 140: s = "\"%\" expected"; break;
			case 141: s = "\"->\" expected"; break;
			case 142: s = "??? expected"; break;
			case 143: s = "invalid NamespaceMemberDeclaration"; break;
			case 144: s = "invalid Attributes"; break;
			case 145: s = "invalid TypeDeclaration"; break;
			case 146: s = "invalid TypeDeclaration"; break;
			case 147: s = "invalid TypeParameterConstraintsClause"; break;
			case 148: s = "invalid IntegralType"; break;
			case 149: s = "invalid Type"; break;
			case 150: s = "invalid FormalParameterList"; break;
			case 151: s = "invalid ClassType"; break;
			case 152: s = "invalid ClassMemberDeclaration"; break;
			case 153: s = "invalid ClassMemberDeclaration"; break;
			case 154: s = "invalid InterfaceMemberDeclaration"; break;
			case 155: s = "invalid InterfaceMemberDeclaration"; break;
			case 156: s = "invalid InterfaceMemberDeclaration"; break;
			case 157: s = "invalid StructMemberDeclaration"; break;
			case 158: s = "invalid StructMemberDeclaration"; break;
			case 159: s = "invalid StructMemberDeclaration"; break;
			case 160: s = "invalid StructMemberDeclaration"; break;
			case 161: s = "invalid StructMemberDeclaration"; break;
			case 162: s = "invalid StructMemberDeclaration"; break;
			case 163: s = "invalid StructMemberDeclaration"; break;
			case 164: s = "invalid StructMemberDeclaration"; break;
			case 165: s = "invalid StructMemberDeclaration"; break;
			case 166: s = "invalid StructMemberDeclaration"; break;
			case 167: s = "invalid StructMemberDeclaration"; break;
			case 168: s = "invalid Expression"; break;
			case 169: s = "invalid Expression"; break;
			case 170: s = "invalid Expression"; break;
			case 171: s = "invalid EventAccessorDeclarations"; break;
			case 172: s = "invalid EventAccessorDeclarations"; break;
			case 173: s = "invalid OverloadableOp"; break;
			case 174: s = "invalid AccessorDeclarations"; break;
			case 175: s = "invalid AccessorDeclarations"; break;
			case 176: s = "invalid AccessorDeclarations"; break;
			case 177: s = "invalid AccessorDeclarations"; break;
			case 178: s = "invalid InterfaceAccessors"; break;
			case 179: s = "invalid InterfaceAccessors"; break;
			case 180: s = "invalid LocalVariableDeclarator"; break;
			case 181: s = "invalid LocalVariableDeclarator"; break;
			case 182: s = "invalid VariableInitializer"; break;
			case 183: s = "invalid Keyword"; break;
			case 184: s = "invalid AttributeArguments"; break;
			case 185: s = "invalid PrimitiveType"; break;
			case 186: s = "invalid PointerOrArray"; break;
			case 187: s = "invalid ResolvedType"; break;
			case 188: s = "invalid TypeArgumentList"; break;
			case 189: s = "invalid TypeArgumentList"; break;
			case 190: s = "invalid InternalClassType"; break;
			case 191: s = "invalid Statement"; break;
			case 192: s = "invalid EmbeddedStatement"; break;
			case 193: s = "invalid EmbeddedStatement"; break;
			case 194: s = "invalid EmbeddedStatement"; break;
			case 195: s = "invalid EmbeddedStatement"; break;
			case 196: s = "invalid StatementExpression"; break;
			case 197: s = "invalid ForInitializer"; break;
			case 198: s = "invalid CatchClauses"; break;
			case 199: s = "invalid ResourceAcquisition"; break;
			case 200: s = "invalid Unary"; break;
			case 201: s = "invalid AssignmentOperator"; break;
			case 202: s = "invalid SwitchLabel"; break;
			case 203: s = "invalid ImplicitLambdaExpression"; break;
			case 204: s = "invalid ShiftExpr"; break;
			case 205: s = "invalid Primary"; break;
			case 206: s = "invalid Primary"; break;
			case 207: s = "invalid Primary"; break;
			case 208: s = "invalid Literal"; break;
			case 209: s = "invalid MemberOrElementInitializer"; break;
			case 210: s = "invalid MemberOrElementInitializer"; break;
			case 211: s = "invalid ImplicitTypedLambdaBody"; break;
			case 212: s = "invalid QueryBody"; break;
			case 213: s = "invalid QueryBodyClause"; break;

			default: s = "error " + n; break;
		}
		errorStream.WriteLine(errMsgFormat, line, col, s);
		count++;
	}

	public virtual void SemErr (int line, int col, string s) {
		errorStream.WriteLine(errMsgFormat, line, col, s);
		count++;
	}
	
	public virtual void SemErr (string s) {
		errorStream.WriteLine(s);
		count++;
	}
	
	public virtual void Warning (int line, int col, string s) {
		errorStream.WriteLine(errMsgFormat, line, col, s);
	}
	
	public virtual void Warning(string s) {
		errorStream.WriteLine(s);
	}
} // Errors


public class FatalError: Exception {
	public FatalError(string m): base(m) {}
}
}